Compare commits

...

52 Commits

Author SHA1 Message Date
Vikhyath Mondreti
11dc18a80d v0.5.74: autolayout improvements, clerk integration, auth enforcements 2026-01-27 20:37:39 -08:00
Vikhyath Mondreti
0d0209a108 fix(autolayout): pass through gridsize (#3042)
* fix(autolayout): pass through gridsize

* fix tests
2026-01-27 20:09:26 -08:00
Vikhyath Mondreti
500dcd4734 fix(openrouter): ignored when tools are configured but unused (#3041) 2026-01-27 19:43:44 -08:00
Vikhyath Mondreti
8bdba373c6 improvement(function): timeout increase to 5 min (#3040) 2026-01-27 19:32:11 -08:00
Vikhyath Mondreti
c8ffda1616 fix(gemini): token count (#3039)
* fix(gemini): token count

* fix to include tool call tokens
2026-01-27 19:16:54 -08:00
Waleed
b4a389a71f improvement(helm): update GPU device plugin and add cert-manager issuers (#3036)
* improvement(helm): update GPU device plugin and add cert-manager issuers

* fix(helm): address code review feedback for GPU plugin and cert-manager

* fix(helm): remove duplicate nodeSelector, add hook for CA issuer ordering

* fix(helm): remove incorrect hook, CA issuer auto-reconciles
2026-01-27 18:25:08 -08:00
Vikhyath Mondreti
65bc21608c improvement(block-inputs): must parse json accurately + models max_tokens fix (#3033)
* improvement(block-inputs): must parse json accurately

* fix sheets typing

* add reference comment

* fix models

* revert blocks changes

* fix param to follow openai new convention
2026-01-27 18:17:35 -08:00
Waleed
ef613ef035 fix(models): update cerebras and groq models (#3038) 2026-01-27 18:12:48 -08:00
Waleed
20b76e67b3 improvement(skills): extend skills (#3035) 2026-01-27 17:58:58 -08:00
Waleed
7640fdf742 feat(autolayout): add snap-to-grid support (#3031)
* feat(autolayout): add snap-to-grid support

* fix(autolayout): recalculate dimensions after grid snapping

* fix(autolayout): correct dimension calculation and propagate gridSize
2026-01-27 17:02:27 -08:00
Waleed
bca355c36d feat(tools): added clerk tools and block (#3032)
* feat(tools): added clerk tools and block

* updated docs gen script

* use clerk api types
2026-01-27 16:45:48 -08:00
Vikhyath Mondreti
089427822e fix(hitl): add missing fields to block configs (#3027)
* fix(hitl): add missing fields to block configs

* update copilot paths

* one more case

* update helper usage
2026-01-27 14:35:37 -08:00
Waleed
ab4e9dc72f v0.5.73: ci, helm updates, kb, ui fixes, note block enhancements 2026-01-26 22:04:35 -08:00
Vikhyath Mondreti
1c58c35bd8 v0.5.72: azure connection string, supabase improvement, multitrigger resolution, docs quick reference 2026-01-25 23:42:27 -08:00
Waleed
d63a5cb504 v0.5.71: ux, ci improvements, docs updates 2026-01-25 03:08:08 -08:00
Waleed
8bd5d41723 v0.5.70: router fix, anthropic agent response format adherence 2026-01-24 20:57:02 -08:00
Waleed
c12931bc50 v0.5.69: kb upgrades, blog, copilot improvements, auth consolidation (#2973)
* fix(subflows): tag dropdown + resolution logic (#2949)

* fix(subflows): tag dropdown + resolution logic

* fixes;

* revert parallel change

* chore(deps): bump posthog-js to 1.334.1 (#2948)

* fix(idempotency): add conflict target to atomicallyClaimDb query + remove redundant db namespace tracking (#2950)

* fix(idempotency): add conflict target to atomicallyClaimDb query

* delete needs to account for namespace

* simplify namespace filtering logic

* fix cleanup

* consistent target

* improvement(kb): add document filtering, select all, and React Query migration (#2951)

* improvement(kb): add document filtering, select all, and React Query migration

* test(kb): update tests for enabledFilter and removed userId params

* fix(kb): remove non-null assertion, add explicit guard

* improvement(logs): trace span, details (#2952)

* improvement(action-bar): ordering

* improvement(logs): details, trace span

* feat(blog): v0.5 release post (#2953)

* feat(blog): v0.5 post

* improvement(blog): simplify title and remove code block header

- Simplified blog title from Introducing Sim Studio v0.5 to Introducing Sim v0.5
- Removed language label header and copy button from code blocks for cleaner appearance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* ack PR comments

* small styling improvements

* created system to create post-specific components

* updated componnet

* cache invalidation

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* feat(admin): add credits endpoint to issue credits to users (#2954)

* feat(admin): add credits endpoint to issue credits to users

* fix(admin): use existing credit functions and handle enterprise seats

* fix(admin): reject NaN and Infinity in amount validation

* styling

* fix(admin): validate userId and email are strings

* improvement(copilot): fast mode, subagent tool responses and allow preferences (#2955)

* Improvements

* Fix actions mapping

* Remove console logs

* fix(billing): handle missing userStats and prevent crashes (#2956)

* fix(billing): handle missing userStats and prevent crashes

* fix(billing): correct import path for getFilledPillColor

* fix(billing): add Number.isFinite check to lastPeriodCost

* fix(logs): refresh logic to refresh logs details (#2958)

* fix(security): add authentication and input validation to API routes (#2959)

* fix(security): add authentication and input validation to API routes

* moved utils

* remove extraneous commetns

* removed unused dep

* improvement(helm): add internal ingress support and same-host path consolidation (#2960)

* improvement(helm): add internal ingress support and same-host path consolidation

* improvement(helm): clean up ingress template comments

Simplify verbose inline Helm comments and section dividers to match the
minimal style used in services.yaml.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(helm): add missing copilot path consolidation for realtime host

When copilot.host equals realtime.host but differs from app.host,
copilot paths were not being routed. Added logic to consolidate
copilot paths into the realtime rule for this scenario.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* improvement(helm): follow ingress best practices

- Remove orphan comments that appeared when services were disabled
- Add documentation about path ordering requirements
- Paths rendered in order: realtime, copilot, app (specific before catch-all)
- Clean template output matching industry Helm chart standards

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* feat(blog): enterprise post (#2961)

* feat(blog): enterprise post

* added more images, styling

* more content

* updated v0-5 post

* remove unused transition

---------

Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>

* fix(envvars): resolution standardized (#2957)

* fix(envvars): resolution standardized

* remove comments

* address bugbot

* fix highlighting for env vars

* remove comments

* address greptile

* address bugbot

* fix(copilot): mask credentials fix (#2963)

* Fix copilot masking

* Clean up

* Lint

* improvement(webhooks): remove dead code (#2965)

* fix(webhooks): subscription recreation path

* improvement(webhooks): remove dead code

* fix tests

* address bugbot comments

* fix restoration edge case

* fix more edge cases

* address bugbot comments

* fix gmail polling

* add warnings for UI indication for credential sets

* fix(preview): subblock values (#2969)

* fix(child-workflow): nested spans handoff (#2966)

* fix(child-workflow): nested spans handoff

* remove overly defensive programming

* update type check

* type more code

* remove more dead code

* address bugbot comments

* fix(security): restrict API key access on internal-only routes (#2964)

* fix(security): restrict API key access on internal-only routes

* test(security): update function execute tests for checkInternalAuth

* updated agent handler

* move session check higher in checkSessionOrInternalAuth

* extracted duplicate code into helper for resolving user from jwt

* fix(copilot): update copilot chat title (#2968)

* fix(hitl): fix condition blocks after hitl (#2967)

* fix(notes): ghost edges (#2970)

* fix(notes): ghost edges

* fix deployed state fallback

* fallback

* remove UI level checks

* annotation missing from autoconnect source check

* improvement(docs): loop and parallel var reference syntax (#2975)

* fix(blog): slash actions description (#2976)

* improvement(docs): loop and parallel var reference syntax

* fix(blog): slash actions description

* fix(auth): copilot routes (#2977)

* Fix copilot auth

* Fix

* Fix

* Fix

* fix(copilot): fix edit summary for loops/parallels (#2978)

* fix(integrations): hide from tool bar (#2544)

* fix(landing): ui (#2979)

* fix(edge-validation): race condition on collaborative add (#2980)

* fix(variables): boolean type support and input improvements (#2981)

* fix(variables): boolean type support and input improvements

* fix formatting

---------

Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
Co-authored-by: Emir Karabeg <78010029+emir-karabeg@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Siddharth Ganesan <33737564+Sg312@users.noreply.github.com>
Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
2026-01-24 14:29:53 -08:00
Waleed
e9c4251c1c v0.5.68: router block reasoning, executor improvements, variable resolution consolidation, helm updates (#2946)
* improvement(workflow-item): stabilize avatar layout and fix name truncation (#2939)

* improvement(workflow-item): stabilize avatar layout and fix name truncation

* fix(avatars): revert overflow bg to hardcoded color for contrast

* fix(executor): stop parallel execution when block errors (#2940)

* improvement(helm): add per-deployment extraVolumes support (#2942)

* fix(gmail): expose messageId field in read email block (#2943)

* fix(resolver): consolidate reference resolution  (#2941)

* fix(resolver): consolidate code to resolve references

* fix edge cases

* use already formatted error

* fix multi index

* fix backwards compat reachability

* handle backwards compatibility accurately

* use shared constant correctly

* feat(router): expose reasoning output in router v2 block (#2945)

* fix(copilot): always allow, credential masking (#2947)

* Fix always allow, credential validation

* Credential masking

* Autoload

* fix(executor): handle condition dead-end branches in loops (#2944)

---------

Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
Co-authored-by: Siddharth Ganesan <33737564+Sg312@users.noreply.github.com>
2026-01-22 13:48:15 -08:00
Waleed
cc2be33d6b v0.5.67: loading, password reset, ui improvements, helm updates (#2928)
* fix(zustand): updated to useShallow from deprecated createWithEqualityFn (#2919)

* fix(logger): use direct env access for webpack inlining (#2920)

* fix(notifications): text overflow with line-clamp (#2921)

* chore(helm): add env vars for Vertex AI, orgs, and telemetry (#2922)

* fix(auth): improve reset password flow and consolidate brand detection (#2924)

* fix(auth): improve reset password flow and consolidate brand detection

* fix(auth): set errorHandled for EMAIL_NOT_VERIFIED to prevent duplicate error

* fix(auth): clear success message on login errors

* chore(auth): fix import order per lint

* fix(action-bar): duplicate subflows with children (#2923)

* fix(action-bar): duplicate subflows with children

* fix(action-bar): add validateTriggerPaste for subflow duplicate

* fix(resolver): agent response format, input formats, root level (#2925)

* fix(resolvers): agent response format, input formats, root level

* fix response block initial seeding

* fix tests

* fix(messages-input): fix cursor alignment and auto-resize with overlay (#2926)

* fix(messages-input): fix cursor alignment and auto-resize with overlay

* fixed remaining zustand warnings

* fix(stores): remove dead code causing log spam on startup (#2927)

* fix(stores): remove dead code causing log spam on startup

* fix(stores): replace custom tools zustand store with react query cache

* improvement(ui): use BrandedButton and BrandedLink components (#2930)

- Refactor auth forms to use BrandedButton component
- Add BrandedLink component for changelog page
- Reduce code duplication in login, signup, reset-password forms
- Update star count default value

* fix(custom-tools): remove unsafe title fallback in getCustomTool (#2929)

* fix(custom-tools): remove unsafe title fallback in getCustomTool

* fix(custom-tools): restore title fallback in getCustomTool lookup

Custom tools are referenced by title (custom_${title}), not database ID.
The title fallback is required for client-side tool resolution to work.

* fix(null-bodies): empty bodies handling (#2931)

* fix(null-statuses): empty bodies handling

* address bugbot comment

* fix(token-refresh): microsoft, notion, x, linear (#2933)

* fix(microsoft): proactive refresh needed

* fix(x): missing token refresh flag

* notion and linear missing flag too

* address bugbot comment

* fix(auth): handle EMAIL_NOT_VERIFIED in onError callback (#2932)

* fix(auth): handle EMAIL_NOT_VERIFIED in onError callback

* refactor(auth): extract redirectToVerify helper to reduce duplication

* fix(workflow-selector): use dedicated selector for workflow dropdown (#2934)

* feat(workflow-block): preview (#2935)

* improvement(copilot): tool configs to show nested props (#2936)

* fix(auth): add genericOAuth providers to trustedProviders (#2937)

---------

Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
Co-authored-by: Emir Karabeg <78010029+emir-karabeg@users.noreply.github.com>
2026-01-21 22:53:25 -08:00
Vikhyath Mondreti
45371e521e v0.5.66: external http requests fix, ring highlighting 2026-01-21 02:55:39 -08:00
Waleed
0ce0f98aa5 v0.5.65: gemini updates, textract integration, ui updates (#2909)
* fix(google): wrap primitive tool responses for Gemini API compatibility (#2900)

* fix(canonical): copilot path + update parent (#2901)

* fix(rss): add top-level title, link, pubDate fields to RSS trigger output (#2902)

* fix(rss): add top-level title, link, pubDate fields to RSS trigger output

* fix(imap): add top-level fields to IMAP trigger output

* improvement(browseruse): add profile id param (#2903)

* improvement(browseruse): add profile id param

* make request a stub since we have directExec

* improvement(executor): upgraded abort controller to handle aborts for loops and parallels (#2880)

* improvement(executor): upgraded abort controller to handle aborts for loops and parallels

* comments

* improvement(files): update execution for passing base64 strings (#2906)

* progress

* improvement(execution): update execution for passing base64 strings

* fix types

* cleanup comments

* path security vuln

* reject promise correctly

* fix redirect case

* remove proxy routes

* fix tests

* use ipaddr

* feat(tools): added textract, added v2 for mistral, updated tag dropdown (#2904)

* feat(tools): added textract

* cleanup

* ack pr comments

* reorder

* removed upload for textract async version

* fix additional fields dropdown in editor, update parser to leave validation to be done on the server

* added mistral v2, files v2, and finalized textract

* updated the rest of the old file patterns, updated mistral outputs for v2

* updated tag dropdown to parse non-operation fields as well

* updated extension finder

* cleanup

* added description for inputs to workflow

* use helper for internal route check

* fix tag dropdown merge conflict change

* remove duplicate code

---------

Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>

* fix(ui): change add inputs button to match output selector (#2907)

* fix(canvas): removed invite to workspace from canvas popover (#2908)

* fix(canvas): removed invite to workspace

* removed unused props

* fix(copilot): legacy tool display names (#2911)

* fix(a2a): canonical merge  (#2912)

* fix canonical merge

* fix empty array case

* fix(change-detection): copilot diffs have extra field (#2913)

* improvement(logs): improved logs ui bugs, added subflow disable UI (#2910)

* improvement(logs): improved logs ui bugs, added subflow disable UI

* added duplicate to action bar for subflows

* feat(broadcast): email v0.5 (#2905)

---------

Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
Co-authored-by: Emir Karabeg <78010029+emir-karabeg@users.noreply.github.com>
2026-01-20 23:54:55 -08:00
Waleed
dff1c9d083 v0.5.64: unsubscribe, search improvements, metrics, additional SSO configuration 2026-01-20 00:34:11 -08:00
Vikhyath Mondreti
b09f683072 v0.5.63: ui and performance improvements, more google tools 2026-01-18 15:22:42 -08:00
Vikhyath Mondreti
a8bb0db660 v0.5.62: webhook bug fixes, seeding default subblock values, block selection fixes 2026-01-16 20:27:06 -08:00
Waleed
af82820a28 v0.5.61: webhook improvements, workflow controls, react query for deployment status, chat fixes, reducto and pulse OCR, linear fixes 2026-01-16 18:06:23 -08:00
Waleed
4372841797 v0.5.60: invitation flow improvements, chat fixes, a2a improvements, additional copilot actions 2026-01-15 00:02:18 -08:00
Waleed
5e8c843241 v0.5.59: a2a support, documentation 2026-01-13 13:21:21 -08:00
Waleed
7bf3d73ee6 v0.5.58: export folders, new tools, permissions groups enhancements 2026-01-13 00:56:59 -08:00
Vikhyath Mondreti
7ffc11a738 v0.5.57: subagents, context menu improvements, bug fixes 2026-01-11 11:38:40 -08:00
Waleed
be578e2ed7 v0.5.56: batch operations, access control and permission groups, billing fixes 2026-01-10 00:31:34 -08:00
Waleed
f415e5edc4 v0.5.55: polling groups, bedrock provider, devcontainer fixes, workflow preview enhancements 2026-01-08 23:36:56 -08:00
Waleed
13a6e6c3fa v0.5.54: seo, model blacklist, helm chart updates, fireflies integration, autoconnect improvements, billing fixes 2026-01-07 16:09:45 -08:00
Waleed
f5ab7f21ae v0.5.53: hotkey improvements, added redis fallback, fixes for workflow tool 2026-01-06 23:34:52 -08:00
Waleed
bfb6fffe38 v0.5.52: new port-based router block, combobox expression and variable support 2026-01-06 16:14:10 -08:00
Waleed
4fbec0a43f v0.5.51: triggers, kb, condition block improvements, supabase and grain integration updates 2026-01-06 14:26:46 -08:00
Waleed
585f5e365b v0.5.50: import improvements, ui upgrades, kb styling and performance improvements 2026-01-05 00:35:55 -08:00
Waleed
3792bdd252 v0.5.49: hitl improvements, new email styles, imap trigger, logs context menu (#2672)
* feat(logs-context-menu): consolidated logs utils and types, added logs record context menu (#2659)

* feat(email): welcome email; improvement(emails): ui/ux (#2658)

* feat(email): welcome email; improvement(emails): ui/ux

* improvement(emails): links, accounts, preview

* refactor(emails): file structure and wrapper components

* added envvar for personal emails sent, added isHosted gate

* fixed failing tests, added env mock

* fix: removed comment

---------

Co-authored-by: waleed <walif6@gmail.com>

* fix(logging): hitl + trigger dev crash protection (#2664)

* hitl gaps

* deal with trigger worker crashes

* cleanup import strcuture

* feat(imap): added support for imap trigger (#2663)

* feat(tools): added support for imap trigger

* feat(imap): added parity, tested

* ack PR comments

* final cleanup

* feat(i18n): update translations (#2665)

Co-authored-by: waleedlatif1 <waleedlatif1@users.noreply.github.com>

* fix(grain): updated grain trigger to auto-establish trigger (#2666)

Co-authored-by: aadamgough <adam@sim.ai>

* feat(admin): routes to manage deployments (#2667)

* feat(admin): routes to manage deployments

* fix naming fo deployed by

* feat(time-picker): added timepicker emcn component, added to playground, added searchable prop for dropdown, added more timezones for schedule, updated license and notice date (#2668)

* feat(time-picker): added timepicker emcn component, added to playground, added searchable prop for dropdown, added more timezones for schedule, updated license and notice date

* removed unused params, cleaned up redundant utils

* improvement(invite): aligned styling (#2669)

* improvement(invite): aligned with rest of app

* fix(invite): error handling

* fix: addressed comments

---------

Co-authored-by: Emir Karabeg <78010029+emir-karabeg@users.noreply.github.com>
Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
Co-authored-by: waleedlatif1 <waleedlatif1@users.noreply.github.com>
Co-authored-by: Adam Gough <77861281+aadamgough@users.noreply.github.com>
Co-authored-by: aadamgough <adam@sim.ai>
2026-01-03 13:19:18 -08:00
Waleed
eb5d1f3e5b v0.5.48: copy-paste workflow blocks, docs updates, mcp tool fixes 2025-12-31 18:00:04 -08:00
Waleed
54ab82c8dd v0.5.47: deploy workflow as mcp, kb chunks tokenizer, UI improvements, jira service management tools 2025-12-30 23:18:58 -08:00
Waleed
f895bf469b v0.5.46: build improvements, greptile, light mode improvements 2025-12-29 02:17:52 -08:00
Waleed
dd3209af06 v0.5.45: light mode fixes, realtime usage indicator, docker build improvements 2025-12-27 19:57:42 -08:00
Waleed
b6ba3b50a7 v0.5.44: keyboard shortcuts, autolayout, light mode, byok, testing improvements 2025-12-26 21:25:19 -08:00
Waleed
b304233062 v0.5.43: export logs, circleback, grain, vertex, code hygiene, schedule improvements 2025-12-23 19:19:18 -08:00
Vikhyath Mondreti
57e4b49bd6 v0.5.42: fix memory migration 2025-12-23 01:24:54 -08:00
Vikhyath Mondreti
e12dd204ed v0.5.41: memory fixes, copilot improvements, knowledgebase improvements, LLM providers standardization 2025-12-23 00:15:18 -08:00
Vikhyath Mondreti
3d9d9cbc54 v0.5.40: supabase ops to allow non-public schemas, jira uuid 2025-12-21 22:28:05 -08:00
Waleed
0f4ec962ad v0.5.39: notion, workflow variables fixes 2025-12-20 20:44:00 -08:00
Waleed
4827866f9a v0.5.38: snap to grid, copilot ux improvements, billing line items 2025-12-20 17:24:38 -08:00
Waleed
3e697d9ed9 v0.5.37: redaction utils consolidation, logs updates, autoconnect improvements, additional kb tag types 2025-12-19 22:31:55 -08:00
Martin Yankov
4431a1a484 fix(helm): add custom egress rules to realtime network policy (#2481)
The realtime service network policy was missing the custom egress rules section
that allows configuration of additional egress rules via values.yaml. This caused
the realtime pods to be unable to connect to external databases (e.g., PostgreSQL
on port 5432) when using external database configurations.

The app network policy already had this section, but the realtime network policy
was missing it, creating an inconsistency and preventing the realtime service
from accessing external databases configured via networkPolicy.egress values.

This fix adds the same custom egress rules template section to the realtime
network policy, matching the app network policy behavior and allowing users to
configure database connectivity via values.yaml.
2025-12-19 18:59:08 -08:00
Waleed
4d1a9a3f22 v0.5.36: hitl improvements, opengraph, slack fixes, one-click unsubscribe, auth checks, new db indexes 2025-12-19 01:27:49 -08:00
Vikhyath Mondreti
eb07a080fb v0.5.35: helm updates, copilot improvements, 404 for docs, salesforce fixes, subflow resize clamping 2025-12-18 16:23:19 -08:00
96 changed files with 3920 additions and 1207 deletions

View File

@@ -55,21 +55,21 @@ export const {serviceName}{Action}Tool: ToolConfig<
}, },
params: { params: {
// Hidden params (system-injected) // Hidden params (system-injected, only use hidden for oauth accessToken)
accessToken: { accessToken: {
type: 'string', type: 'string',
required: true, required: true,
visibility: 'hidden', visibility: 'hidden',
description: 'OAuth access token', description: 'OAuth access token',
}, },
// User-only params (credentials, IDs user must provide) // User-only params (credentials, api key, IDs user must provide)
someId: { someId: {
type: 'string', type: 'string',
required: true, required: true,
visibility: 'user-only', visibility: 'user-only',
description: 'The ID of the resource', description: 'The ID of the resource',
}, },
// User-or-LLM params (can be provided by user OR computed by LLM) // User-or-LLM params (everything else, can be provided by user OR computed by LLM)
query: { query: {
type: 'string', type: 'string',
required: false, // Use false for optional required: false, // Use false for optional
@@ -114,8 +114,8 @@ export const {serviceName}{Action}Tool: ToolConfig<
### Visibility Options ### Visibility Options
- `'hidden'` - System-injected (OAuth tokens, internal params). User never sees. - `'hidden'` - System-injected (OAuth tokens, internal params). User never sees.
- `'user-only'` - User must provide (credentials, account-specific IDs) - `'user-only'` - User must provide (credentials, api keys, account-specific IDs)
- `'user-or-llm'` - User provides OR LLM can compute (search queries, content, filters) - `'user-or-llm'` - User provides OR LLM can compute (search queries, content, filters, most fall into this category)
### Parameter Types ### Parameter Types
- `'string'` - Text values - `'string'` - Text values

View File

@@ -2096,6 +2096,23 @@ export function ClayIcon(props: SVGProps<SVGSVGElement>) {
) )
} }
export function ClerkIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} viewBox='0 0 128 128' fill='none' xmlns='http://www.w3.org/2000/svg'>
<circle cx='64' cy='64' r='20' fill='white' />
<path
d='M99.5716 10.788C101.571 12.1272 101.742 14.9444 100.04 16.646L85.4244 31.2618C84.1035 32.5828 82.0542 32.7914 80.3915 31.9397C75.4752 29.421 69.9035 28 64 28C44.1177 28 28 44.1177 28 64C28 69.9035 29.421 75.4752 31.9397 80.3915C32.7914 82.0542 32.5828 84.1035 31.2618 85.4244L16.646 100.04C14.9444 101.742 12.1272 101.571 10.788 99.5716C3.97411 89.3989 0 77.1635 0 64C0 28.6538 28.6538 0 64 0C77.1635 0 89.3989 3.97411 99.5716 10.788Z'
fill='white'
fillOpacity='0.4'
/>
<path
d='M100.04 111.354C101.742 113.056 101.571 115.873 99.5717 117.212C89.3989 124.026 77.1636 128 64 128C50.8364 128 38.6011 124.026 28.4283 117.212C26.4289 115.873 26.2581 113.056 27.9597 111.354L42.5755 96.7382C43.8965 95.4172 45.9457 95.2085 47.6084 96.0603C52.5248 98.579 58.0964 100 64 100C69.9036 100 75.4753 98.579 80.3916 96.0603C82.0543 95.2085 84.1036 95.4172 85.4245 96.7382L100.04 111.354Z'
fill='white'
/>
</svg>
)
}
export function MicrosoftIcon(props: SVGProps<SVGSVGElement>) { export function MicrosoftIcon(props: SVGProps<SVGSVGElement>) {
return ( return (
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 23 23' {...props}> <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 23 23' {...props}>

View File

@@ -16,6 +16,7 @@ import {
CalendlyIcon, CalendlyIcon,
CirclebackIcon, CirclebackIcon,
ClayIcon, ClayIcon,
ClerkIcon,
ConfluenceIcon, ConfluenceIcon,
CursorIcon, CursorIcon,
DatadogIcon, DatadogIcon,
@@ -143,6 +144,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
calendly: CalendlyIcon, calendly: CalendlyIcon,
circleback: CirclebackIcon, circleback: CirclebackIcon,
clay: ClayIcon, clay: ClayIcon,
clerk: ClerkIcon,
confluence_v2: ConfluenceIcon, confluence_v2: ConfluenceIcon,
cursor_v2: CursorIcon, cursor_v2: CursorIcon,
datadog: DatadogIcon, datadog: DatadogIcon,

View File

@@ -168,10 +168,10 @@ Search for tasks in an Asana workspace
| `success` | boolean | Operation success status | | `success` | boolean | Operation success status |
| `ts` | string | Timestamp of the response | | `ts` | string | Timestamp of the response |
| `tasks` | array | Array of matching tasks | | `tasks` | array | Array of matching tasks |
| ↳ `gid` | string | Assignee GID | | ↳ `gid` | string | Task GID |
| ↳ `resource_type` | string | Resource type | | ↳ `resource_type` | string | Resource type |
| ↳ `resource_subtype` | string | Resource subtype | | ↳ `resource_subtype` | string | Resource subtype |
| ↳ `name` | string | Assignee name | | ↳ `name` | string | Task name |
| ↳ `notes` | string | Task notes | | ↳ `notes` | string | Task notes |
| ↳ `completed` | boolean | Completion status | | ↳ `completed` | boolean | Completion status |
| ↳ `assignee` | object | Assignee details | | ↳ `assignee` | object | Assignee details |

View File

@@ -116,7 +116,7 @@ Get detailed information about a specific event type
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `resource` | object | Event type details | | `resource` | object | Event type details |
| ↳ `uri` | string | Canonical reference to the event type | | ↳ `uri` | string | Canonical reference to the event type |
| ↳ `name` | string | Question text | | ↳ `name` | string | Event type name |
| ↳ `active` | boolean | Whether the event type is active | | ↳ `active` | boolean | Whether the event type is active |
| ↳ `booking_method` | string | Booking method | | ↳ `booking_method` | string | Booking method |
| ↳ `color` | string | Hex color code | | ↳ `color` | string | Hex color code |
@@ -128,16 +128,12 @@ Get detailed information about a specific event type
| ↳ `enabled` | boolean | Whether question is enabled | | ↳ `enabled` | boolean | Whether question is enabled |
| ↳ `required` | boolean | Whether question is required | | ↳ `required` | boolean | Whether question is required |
| ↳ `answer_choices` | array | Available answer choices | | ↳ `answer_choices` | array | Available answer choices |
| ↳ `type` | string | Event type classification |
| ↳ `position` | number | Question order |
| ↳ `enabled` | boolean | Whether question is enabled |
| ↳ `required` | boolean | Whether question is required |
| ↳ `answer_choices` | array | Available answer choices |
| ↳ `description_html` | string | HTML formatted description | | ↳ `description_html` | string | HTML formatted description |
| ↳ `description_plain` | string | Plain text description | | ↳ `description_plain` | string | Plain text description |
| ↳ `duration` | number | Duration in minutes | | ↳ `duration` | number | Duration in minutes |
| ↳ `scheduling_url` | string | URL to scheduling page | | ↳ `scheduling_url` | string | URL to scheduling page |
| ↳ `slug` | string | Unique identifier for URLs | | ↳ `slug` | string | Unique identifier for URLs |
| ↳ `type` | string | Event type classification |
| ↳ `updated_at` | string | ISO timestamp of last update | | ↳ `updated_at` | string | ISO timestamp of last update |
### `calendly_list_scheduled_events` ### `calendly_list_scheduled_events`
@@ -170,16 +166,14 @@ Retrieve a list of scheduled events for a user or organization
| ↳ `start_time` | string | ISO timestamp of event start | | ↳ `start_time` | string | ISO timestamp of event start |
| ↳ `end_time` | string | ISO timestamp of event end | | ↳ `end_time` | string | ISO timestamp of event end |
| ↳ `event_type` | string | URI of the event type | | ↳ `event_type` | string | URI of the event type |
| ↳ `location` | string | Location description | | ↳ `location` | object | Event location details |
| ↳ `type` | string | Location type \(e.g., | | ↳ `type` | string | Location type \(e.g., |
| ↳ `location` | string | Location description |
| ↳ `join_url` | string | URL to join online meeting \(if applicable\) | | ↳ `join_url` | string | URL to join online meeting \(if applicable\) |
| ↳ `invitees_counter` | object | Invitee count information | | ↳ `invitees_counter` | object | Invitee count information |
| ↳ `total` | number | Total number of invitees | | ↳ `total` | number | Total number of invitees |
| ↳ `active` | number | Number of active invitees | | ↳ `active` | number | Number of active invitees |
| ↳ `limit` | number | Maximum number of invitees | | ↳ `limit` | number | Maximum number of invitees |
| ↳ `total` | number | Total number of invitees |
| ↳ `active` | number | Number of active invitees |
| ↳ `limit` | number | Maximum number of invitees |
| ↳ `created_at` | string | ISO timestamp of event creation | | ↳ `created_at` | string | ISO timestamp of event creation |
| ↳ `updated_at` | string | ISO timestamp of last update | | ↳ `updated_at` | string | ISO timestamp of last update |
| `pagination` | object | Pagination information | | `pagination` | object | Pagination information |
@@ -211,28 +205,22 @@ Get detailed information about a specific scheduled event
| ↳ `start_time` | string | ISO timestamp of event start | | ↳ `start_time` | string | ISO timestamp of event start |
| ↳ `end_time` | string | ISO timestamp of event end | | ↳ `end_time` | string | ISO timestamp of event end |
| ↳ `event_type` | string | URI of the event type | | ↳ `event_type` | string | URI of the event type |
| ↳ `location` | string | Location description | | ↳ `location` | object | Event location details |
| ↳ `type` | string | Location type | | ↳ `type` | string | Location type |
| ↳ `join_url` | string | URL to join online meeting | | ↳ `location` | string | Location description |
| ↳ `join_url` | string | URL to join online meeting |
| ↳ `invitees_counter` | object | Invitee count information | | ↳ `invitees_counter` | object | Invitee count information |
| ↳ `total` | number | Total number of invitees | | ↳ `total` | number | Total number of invitees |
| ↳ `active` | number | Number of active invitees | | ↳ `active` | number | Number of active invitees |
| ↳ `limit` | number | Maximum number of invitees | | ↳ `limit` | number | Maximum number of invitees |
| ↳ `total` | number | Total number of invitees |
| ↳ `active` | number | Number of active invitees |
| ↳ `limit` | number | Maximum number of invitees |
| ↳ `event_memberships` | array | Event hosts/members | | ↳ `event_memberships` | array | Event hosts/members |
| ↳ `user` | string | User URI | | ↳ `user` | string | User URI |
| ↳ `user_email` | string | User email | | ↳ `user_email` | string | User email |
| ↳ `user_name` | string | User name | | ↳ `user_name` | string | User name |
| ↳ `user` | string | User URI |
| ↳ `user_email` | string | User email |
| ↳ `user_name` | string | User name |
| ↳ `event_guests` | array | Additional guests | | ↳ `event_guests` | array | Additional guests |
| ↳ `email` | string | Guest email | | ↳ `email` | string | Guest email |
| ↳ `created_at` | string | When guest was added | | ↳ `created_at` | string | When guest was added |
| ↳ `updated_at` | string | When guest info was updated | | ↳ `updated_at` | string | When guest info was updated |
| ↳ `email` | string | Guest email |
| ↳ `created_at` | string | ISO timestamp of event creation | | ↳ `created_at` | string | ISO timestamp of event creation |
| ↳ `updated_at` | string | ISO timestamp of last update | | ↳ `updated_at` | string | ISO timestamp of last update |
@@ -267,9 +255,6 @@ Retrieve a list of invitees for a scheduled event
| ↳ `question` | string | Question text | | ↳ `question` | string | Question text |
| ↳ `answer` | string | Invitee answer | | ↳ `answer` | string | Invitee answer |
| ↳ `position` | number | Question order | | ↳ `position` | number | Question order |
| ↳ `question` | string | Question text |
| ↳ `answer` | string | Invitee answer |
| ↳ `position` | number | Question order |
| ↳ `timezone` | string | Invitee timezone | | ↳ `timezone` | string | Invitee timezone |
| ↳ `event` | string | URI of the scheduled event | | ↳ `event` | string | URI of the scheduled event |
| ↳ `created_at` | string | ISO timestamp when invitee was created | | ↳ `created_at` | string | ISO timestamp when invitee was created |

View File

@@ -0,0 +1,442 @@
---
title: Clerk
description: Manage users, organizations, and sessions in Clerk
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="clerk"
color="#131316"
/>
{/* MANUAL-CONTENT-START:intro */}
[Clerk](https://clerk.com/) is a comprehensive identity infrastructure platform that helps you manage users, authentication, and sessions for your applications.
In Sim, the Clerk integration lets your agents automate user and session management through easy-to-use API-based tools. Agents can securely list users, update user profiles, manage organizations, monitor sessions, and revoke access directly in your workflow.
With Clerk, you can:
- **Authenticate users and manage sessions**: Seamlessly control sign-in, sign-up, and session lifecycle for your users.
- **List and update users**: Automatically pull user lists, update user attributes, or view profile details as part of your agent tasks.
- **Manage organizations and memberships**: Add or update organizations and administer user memberships with clarity.
- **Monitor and revoke sessions**: See active or past user sessions, and revoke access immediately if needed for security.
The integration enables real-time, auditable management of your user base—all from within Sim. Connected agents can automate onboarding, enforce policies, keep directories up to date, and react to authentication events or organizational changes, helping you run secure and flexible processes using Clerk as your identity engine.
{/* MANUAL-CONTENT-END */}
## Usage Instructions
Integrate Clerk authentication and user management into your workflow. Create, update, delete, and list users. Manage organizations and their memberships. Monitor and control user sessions.
## Tools
### `clerk_list_users`
List all users in your Clerk application with optional filtering and pagination
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `secretKey` | string | Yes | The Clerk Secret Key for API authentication |
| `limit` | number | No | Number of results per page \(1-500, default: 10\) |
| `offset` | number | No | Number of results to skip for pagination |
| `orderBy` | string | No | Sort field with optional +/- prefix for direction \(default: -created_at\) |
| `emailAddress` | string | No | Filter by email address \(comma-separated for multiple\) |
| `phoneNumber` | string | No | Filter by phone number \(comma-separated for multiple\) |
| `externalId` | string | No | Filter by external ID \(comma-separated for multiple\) |
| `username` | string | No | Filter by username \(comma-separated for multiple\) |
| `userId` | string | No | Filter by user ID \(comma-separated for multiple\) |
| `query` | string | No | Search query to match across email, phone, username, and names |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `users` | array | Array of Clerk user objects |
| ↳ `id` | string | User ID |
| ↳ `username` | string | Username |
| ↳ `firstName` | string | First name |
| ↳ `lastName` | string | Last name |
| ↳ `imageUrl` | string | Profile image URL |
| ↳ `hasImage` | boolean | Whether user has a profile image |
| ↳ `primaryEmailAddressId` | string | Primary email address ID |
| ↳ `primaryPhoneNumberId` | string | Primary phone number ID |
| ↳ `emailAddresses` | array | User email addresses |
| ↳ `id` | string | Email address ID |
| ↳ `emailAddress` | string | Email address |
| ↳ `phoneNumbers` | array | User phone numbers |
| ↳ `id` | string | Phone number ID |
| ↳ `phoneNumber` | string | Phone number |
| ↳ `externalId` | string | External system ID |
| ↳ `passwordEnabled` | boolean | Whether password is enabled |
| ↳ `twoFactorEnabled` | boolean | Whether 2FA is enabled |
| ↳ `banned` | boolean | Whether user is banned |
| ↳ `locked` | boolean | Whether user is locked |
| ↳ `lastSignInAt` | number | Last sign-in timestamp |
| ↳ `lastActiveAt` | number | Last activity timestamp |
| ↳ `createdAt` | number | Creation timestamp |
| ↳ `updatedAt` | number | Last update timestamp |
| ↳ `publicMetadata` | json | Public metadata |
| `totalCount` | number | Total number of users matching the query |
| `success` | boolean | Operation success status |
### `clerk_get_user`
Retrieve a single user by their ID from Clerk
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `secretKey` | string | Yes | The Clerk Secret Key for API authentication |
| `userId` | string | Yes | The ID of the user to retrieve |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | User ID |
| `username` | string | Username |
| `firstName` | string | First name |
| `lastName` | string | Last name |
| `imageUrl` | string | Profile image URL |
| `hasImage` | boolean | Whether user has a profile image |
| `primaryEmailAddressId` | string | Primary email address ID |
| `primaryPhoneNumberId` | string | Primary phone number ID |
| `primaryWeb3WalletId` | string | Primary Web3 wallet ID |
| `emailAddresses` | array | User email addresses |
| ↳ `id` | string | Email address ID |
| ↳ `emailAddress` | string | Email address |
| ↳ `verified` | boolean | Whether email is verified |
| `phoneNumbers` | array | User phone numbers |
| ↳ `id` | string | Phone number ID |
| ↳ `phoneNumber` | string | Phone number |
| ↳ `verified` | boolean | Whether phone is verified |
| `externalId` | string | External system ID |
| `passwordEnabled` | boolean | Whether password is enabled |
| `twoFactorEnabled` | boolean | Whether 2FA is enabled |
| `totpEnabled` | boolean | Whether TOTP is enabled |
| `backupCodeEnabled` | boolean | Whether backup codes are enabled |
| `banned` | boolean | Whether user is banned |
| `locked` | boolean | Whether user is locked |
| `deleteSelfEnabled` | boolean | Whether user can delete themselves |
| `createOrganizationEnabled` | boolean | Whether user can create organizations |
| `lastSignInAt` | number | Last sign-in timestamp |
| `lastActiveAt` | number | Last activity timestamp |
| `createdAt` | number | Creation timestamp |
| `updatedAt` | number | Last update timestamp |
| `publicMetadata` | json | Public metadata \(readable from frontend\) |
| `privateMetadata` | json | Private metadata \(backend only\) |
| `unsafeMetadata` | json | Unsafe metadata \(modifiable from frontend\) |
| `success` | boolean | Operation success status |
### `clerk_create_user`
Create a new user in your Clerk application
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `secretKey` | string | Yes | The Clerk Secret Key for API authentication |
| `emailAddress` | string | No | Email addresses for the user \(comma-separated for multiple\) |
| `phoneNumber` | string | No | Phone numbers for the user \(comma-separated for multiple\) |
| `username` | string | No | Username for the user \(must be unique\) |
| `password` | string | No | Password for the user \(minimum 8 characters\) |
| `firstName` | string | No | First name of the user |
| `lastName` | string | No | Last name of the user |
| `externalId` | string | No | External system identifier \(must be unique\) |
| `publicMetadata` | json | No | Public metadata \(JSON object, readable from frontend\) |
| `privateMetadata` | json | No | Private metadata \(JSON object, backend only\) |
| `unsafeMetadata` | json | No | Unsafe metadata \(JSON object, modifiable from frontend\) |
| `skipPasswordChecks` | boolean | No | Skip password validation checks |
| `skipPasswordRequirement` | boolean | No | Make password optional |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | Created user ID |
| `username` | string | Username |
| `firstName` | string | First name |
| `lastName` | string | Last name |
| `imageUrl` | string | Profile image URL |
| `primaryEmailAddressId` | string | Primary email address ID |
| `primaryPhoneNumberId` | string | Primary phone number ID |
| `emailAddresses` | array | User email addresses |
| ↳ `id` | string | Email address ID |
| ↳ `emailAddress` | string | Email address |
| ↳ `verified` | boolean | Whether email is verified |
| `phoneNumbers` | array | User phone numbers |
| ↳ `id` | string | Phone number ID |
| ↳ `phoneNumber` | string | Phone number |
| ↳ `verified` | boolean | Whether phone is verified |
| `externalId` | string | External system ID |
| `createdAt` | number | Creation timestamp |
| `updatedAt` | number | Last update timestamp |
| `publicMetadata` | json | Public metadata |
| `success` | boolean | Operation success status |
### `clerk_update_user`
Update an existing user in your Clerk application
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `secretKey` | string | Yes | The Clerk Secret Key for API authentication |
| `userId` | string | Yes | The ID of the user to update |
| `firstName` | string | No | First name of the user |
| `lastName` | string | No | Last name of the user |
| `username` | string | No | Username \(must be unique\) |
| `password` | string | No | New password \(minimum 8 characters\) |
| `externalId` | string | No | External system identifier |
| `primaryEmailAddressId` | string | No | ID of verified email to set as primary |
| `primaryPhoneNumberId` | string | No | ID of verified phone to set as primary |
| `publicMetadata` | json | No | Public metadata \(JSON object\) |
| `privateMetadata` | json | No | Private metadata \(JSON object\) |
| `unsafeMetadata` | json | No | Unsafe metadata \(JSON object\) |
| `skipPasswordChecks` | boolean | No | Skip password validation checks |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | Updated user ID |
| `username` | string | Username |
| `firstName` | string | First name |
| `lastName` | string | Last name |
| `imageUrl` | string | Profile image URL |
| `primaryEmailAddressId` | string | Primary email address ID |
| `primaryPhoneNumberId` | string | Primary phone number ID |
| `emailAddresses` | array | User email addresses |
| ↳ `id` | string | Email address ID |
| ↳ `emailAddress` | string | Email address |
| ↳ `verified` | boolean | Whether email is verified |
| `phoneNumbers` | array | User phone numbers |
| ↳ `id` | string | Phone number ID |
| ↳ `phoneNumber` | string | Phone number |
| ↳ `verified` | boolean | Whether phone is verified |
| `externalId` | string | External system ID |
| `banned` | boolean | Whether user is banned |
| `locked` | boolean | Whether user is locked |
| `createdAt` | number | Creation timestamp |
| `updatedAt` | number | Last update timestamp |
| `publicMetadata` | json | Public metadata |
| `success` | boolean | Operation success status |
### `clerk_delete_user`
Delete a user from your Clerk application
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `secretKey` | string | Yes | The Clerk Secret Key for API authentication |
| `userId` | string | Yes | The ID of the user to delete |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | Deleted user ID |
| `object` | string | Object type \(user\) |
| `deleted` | boolean | Whether the user was deleted |
| `success` | boolean | Operation success status |
### `clerk_list_organizations`
List all organizations in your Clerk application with optional filtering
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `secretKey` | string | Yes | The Clerk Secret Key for API authentication |
| `limit` | number | No | Number of results per page \(1-500, default: 10\) |
| `offset` | number | No | Number of results to skip for pagination |
| `includeMembersCount` | boolean | No | Include member count for each organization |
| `query` | string | No | Search by organization ID, name, or slug |
| `orderBy` | string | No | Sort field \(name, created_at, members_count\) with +/- prefix |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `organizations` | array | Array of Clerk organization objects |
| ↳ `id` | string | Organization ID |
| ↳ `name` | string | Organization name |
| ↳ `slug` | string | Organization slug |
| ↳ `imageUrl` | string | Organization image URL |
| ↳ `hasImage` | boolean | Whether organization has an image |
| ↳ `membersCount` | number | Number of members |
| ↳ `pendingInvitationsCount` | number | Number of pending invitations |
| ↳ `maxAllowedMemberships` | number | Max allowed memberships |
| ↳ `adminDeleteEnabled` | boolean | Whether admin delete is enabled |
| ↳ `createdBy` | string | Creator user ID |
| ↳ `createdAt` | number | Creation timestamp |
| ↳ `updatedAt` | number | Last update timestamp |
| ↳ `publicMetadata` | json | Public metadata |
| `totalCount` | number | Total number of organizations |
| `success` | boolean | Operation success status |
### `clerk_get_organization`
Retrieve a single organization by ID or slug from Clerk
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `secretKey` | string | Yes | The Clerk Secret Key for API authentication |
| `organizationId` | string | Yes | The ID or slug of the organization to retrieve |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | Organization ID |
| `name` | string | Organization name |
| `slug` | string | Organization slug |
| `imageUrl` | string | Organization image URL |
| `hasImage` | boolean | Whether organization has an image |
| `membersCount` | number | Number of members |
| `pendingInvitationsCount` | number | Number of pending invitations |
| `maxAllowedMemberships` | number | Max allowed memberships |
| `adminDeleteEnabled` | boolean | Whether admin delete is enabled |
| `createdBy` | string | Creator user ID |
| `createdAt` | number | Creation timestamp |
| `updatedAt` | number | Last update timestamp |
| `publicMetadata` | json | Public metadata |
| `success` | boolean | Operation success status |
### `clerk_create_organization`
Create a new organization in your Clerk application
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `secretKey` | string | Yes | The Clerk Secret Key for API authentication |
| `name` | string | Yes | Name of the organization |
| `createdBy` | string | Yes | User ID of the creator \(will become admin\) |
| `slug` | string | No | Slug identifier for the organization |
| `maxAllowedMemberships` | number | No | Maximum member capacity \(0 for unlimited\) |
| `publicMetadata` | json | No | Public metadata \(JSON object\) |
| `privateMetadata` | json | No | Private metadata \(JSON object\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | Created organization ID |
| `name` | string | Organization name |
| `slug` | string | Organization slug |
| `imageUrl` | string | Organization image URL |
| `hasImage` | boolean | Whether organization has an image |
| `membersCount` | number | Number of members |
| `pendingInvitationsCount` | number | Number of pending invitations |
| `maxAllowedMemberships` | number | Max allowed memberships |
| `adminDeleteEnabled` | boolean | Whether admin delete is enabled |
| `createdBy` | string | Creator user ID |
| `createdAt` | number | Creation timestamp |
| `updatedAt` | number | Last update timestamp |
| `publicMetadata` | json | Public metadata |
| `success` | boolean | Operation success status |
### `clerk_list_sessions`
List sessions for a user or client in your Clerk application
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `secretKey` | string | Yes | The Clerk Secret Key for API authentication |
| `userId` | string | No | User ID to list sessions for \(required if clientId not provided\) |
| `clientId` | string | No | Client ID to list sessions for \(required if userId not provided\) |
| `status` | string | No | Filter by session status \(abandoned, active, ended, expired, pending, removed, replaced, revoked\) |
| `limit` | number | No | Number of results per page \(1-500, default: 10\) |
| `offset` | number | No | Number of results to skip for pagination |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `sessions` | array | Array of Clerk session objects |
| ↳ `id` | string | Session ID |
| ↳ `userId` | string | User ID |
| ↳ `clientId` | string | Client ID |
| ↳ `status` | string | Session status |
| ↳ `lastActiveAt` | number | Last activity timestamp |
| ↳ `lastActiveOrganizationId` | string | Last active organization ID |
| ↳ `expireAt` | number | Expiration timestamp |
| ↳ `abandonAt` | number | Abandon timestamp |
| ↳ `createdAt` | number | Creation timestamp |
| ↳ `updatedAt` | number | Last update timestamp |
| `totalCount` | number | Total number of sessions |
| `success` | boolean | Operation success status |
### `clerk_get_session`
Retrieve a single session by ID from Clerk
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `secretKey` | string | Yes | The Clerk Secret Key for API authentication |
| `sessionId` | string | Yes | The ID of the session to retrieve |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | Session ID |
| `userId` | string | User ID |
| `clientId` | string | Client ID |
| `status` | string | Session status |
| `lastActiveAt` | number | Last activity timestamp |
| `lastActiveOrganizationId` | string | Last active organization ID |
| `expireAt` | number | Expiration timestamp |
| `abandonAt` | number | Abandon timestamp |
| `createdAt` | number | Creation timestamp |
| `updatedAt` | number | Last update timestamp |
| `success` | boolean | Operation success status |
### `clerk_revoke_session`
Revoke a session to immediately invalidate it
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `secretKey` | string | Yes | The Clerk Secret Key for API authentication |
| `sessionId` | string | Yes | The ID of the session to revoke |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | Session ID |
| `userId` | string | User ID |
| `clientId` | string | Client ID |
| `status` | string | Session status \(should be revoked\) |
| `lastActiveAt` | number | Last activity timestamp |
| `lastActiveOrganizationId` | string | Last active organization ID |
| `expireAt` | number | Expiration timestamp |
| `abandonAt` | number | Abandon timestamp |
| `createdAt` | number | Creation timestamp |
| `updatedAt` | number | Last update timestamp |
| `success` | boolean | Operation success status |

View File

@@ -257,11 +257,6 @@ Search and retrieve logs from Datadog. Use for troubleshooting, analysis, or mon
| ↳ `service` | string | Service name | | ↳ `service` | string | Service name |
| ↳ `message` | string | Log message | | ↳ `message` | string | Log message |
| ↳ `status` | string | Log status/level | | ↳ `status` | string | Log status/level |
| ↳ `timestamp` | string | Log timestamp |
| ↳ `host` | string | Host name |
| ↳ `service` | string | Service name |
| ↳ `message` | string | Log message |
| ↳ `status` | string | Log status/level |
| `nextLogId` | string | Cursor for pagination | | `nextLogId` | string | Cursor for pagination |
### `datadog_send_logs` ### `datadog_send_logs`

View File

@@ -64,7 +64,7 @@ Send a message to a Discord channel
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `message` | string | Success or error message | | `message` | string | Success or error message |
| `data` | object | Discord message data | | `data` | object | Discord message data |
| ↳ `id` | string | Author user ID | | ↳ `id` | string | Message ID |
| ↳ `content` | string | Message content | | ↳ `content` | string | Message content |
| ↳ `channel_id` | string | Channel ID where message was sent | | ↳ `channel_id` | string | Channel ID where message was sent |
| ↳ `author` | object | Message author information | | ↳ `author` | object | Message author information |
@@ -72,9 +72,6 @@ Send a message to a Discord channel
| ↳ `username` | string | Author username | | ↳ `username` | string | Author username |
| ↳ `avatar` | string | Author avatar hash | | ↳ `avatar` | string | Author avatar hash |
| ↳ `bot` | boolean | Whether author is a bot | | ↳ `bot` | boolean | Whether author is a bot |
| ↳ `username` | string | Author username |
| ↳ `avatar` | string | Author avatar hash |
| ↳ `bot` | boolean | Whether author is a bot |
| ↳ `timestamp` | string | Message timestamp | | ↳ `timestamp` | string | Message timestamp |
| ↳ `edited_timestamp` | string | Message edited timestamp | | ↳ `edited_timestamp` | string | Message edited timestamp |
| ↳ `embeds` | array | Message embeds | | ↳ `embeds` | array | Message embeds |
@@ -102,7 +99,7 @@ Retrieve messages from a Discord channel
| `message` | string | Success or error message | | `message` | string | Success or error message |
| `data` | object | Container for messages data | | `data` | object | Container for messages data |
| ↳ `messages` | array | Array of Discord messages with full metadata | | ↳ `messages` | array | Array of Discord messages with full metadata |
| ↳ `id` | string | Author user ID | | ↳ `id` | string | Message ID |
| ↳ `content` | string | Message content | | ↳ `content` | string | Message content |
| ↳ `channel_id` | string | Channel ID | | ↳ `channel_id` | string | Channel ID |
| ↳ `author` | object | Message author information | | ↳ `author` | object | Message author information |
@@ -110,9 +107,6 @@ Retrieve messages from a Discord channel
| ↳ `username` | string | Author username | | ↳ `username` | string | Author username |
| ↳ `avatar` | string | Author avatar hash | | ↳ `avatar` | string | Author avatar hash |
| ↳ `bot` | boolean | Whether author is a bot | | ↳ `bot` | boolean | Whether author is a bot |
| ↳ `username` | string | Author username |
| ↳ `avatar` | string | Author avatar hash |
| ↳ `bot` | boolean | Whether author is a bot |
| ↳ `timestamp` | string | Message timestamp | | ↳ `timestamp` | string | Message timestamp |
| ↳ `edited_timestamp` | string | Message edited timestamp | | ↳ `edited_timestamp` | string | Message edited timestamp |
| ↳ `embeds` | array | Message embeds | | ↳ `embeds` | array | Message embeds |
@@ -120,24 +114,7 @@ Retrieve messages from a Discord channel
| ↳ `mentions` | array | User mentions in message | | ↳ `mentions` | array | User mentions in message |
| ↳ `mention_roles` | array | Role mentions in message | | ↳ `mention_roles` | array | Role mentions in message |
| ↳ `mention_everyone` | boolean | Whether message mentions everyone | | ↳ `mention_everyone` | boolean | Whether message mentions everyone |
| ↳ `id` | string | Author user ID |
| ↳ `content` | string | Message content |
| ↳ `channel_id` | string | Channel ID | | ↳ `channel_id` | string | Channel ID |
| ↳ `author` | object | Message author information |
| ↳ `id` | string | Author user ID |
| ↳ `username` | string | Author username |
| ↳ `avatar` | string | Author avatar hash |
| ↳ `bot` | boolean | Whether author is a bot |
| ↳ `username` | string | Author username |
| ↳ `avatar` | string | Author avatar hash |
| ↳ `bot` | boolean | Whether author is a bot |
| ↳ `timestamp` | string | Message timestamp |
| ↳ `edited_timestamp` | string | Message edited timestamp |
| ↳ `embeds` | array | Message embeds |
| ↳ `attachments` | array | Message attachments |
| ↳ `mentions` | array | User mentions in message |
| ↳ `mention_roles` | array | Role mentions in message |
| ↳ `mention_everyone` | boolean | Whether message mentions everyone |
### `discord_get_server` ### `discord_get_server`
@@ -681,9 +658,6 @@ Get information about a member in a Discord server
| ↳ `id` | string | User ID | | ↳ `id` | string | User ID |
| ↳ `username` | string | Username | | ↳ `username` | string | Username |
| ↳ `avatar` | string | Avatar hash | | ↳ `avatar` | string | Avatar hash |
| ↳ `id` | string | User ID |
| ↳ `username` | string | Username |
| ↳ `avatar` | string | Avatar hash |
| ↳ `nick` | string | Server nickname | | ↳ `nick` | string | Server nickname |
| ↳ `roles` | array | Array of role IDs | | ↳ `roles` | array | Array of role IDs |
| ↳ `joined_at` | string | When the member joined | | ↳ `joined_at` | string | When the member joined |

View File

@@ -105,11 +105,6 @@ Crawl entire websites and extract structured content from all accessible pages
| ↳ `language` | string | Page language | | ↳ `language` | string | Page language |
| ↳ `sourceURL` | string | Source URL of the page | | ↳ `sourceURL` | string | Source URL of the page |
| ↳ `statusCode` | number | HTTP status code | | ↳ `statusCode` | number | HTTP status code |
| ↳ `title` | string | Page title |
| ↳ `description` | string | Page description |
| ↳ `language` | string | Page language |
| ↳ `sourceURL` | string | Source URL of the page |
| ↳ `statusCode` | number | HTTP status code |
| `total` | number | Total number of pages found during crawl | | `total` | number | Total number of pages found during crawl |
| `creditsUsed` | number | Number of credits consumed by the crawl operation | | `creditsUsed` | number | Number of credits consumed by the crawl operation |

View File

@@ -1557,20 +1557,20 @@ Search for code across GitHub repositories. Use qualifiers like repo:owner/name,
| `total_count` | number | Total matching results | | `total_count` | number | Total matching results |
| `incomplete_results` | boolean | Whether results are incomplete | | `incomplete_results` | boolean | Whether results are incomplete |
| `items` | array | Array of code matches from GitHub API | | `items` | array | Array of code matches from GitHub API |
| ↳ `name` | string | Repository name | | ↳ `name` | string | File name |
| ↳ `path` | string | File path | | ↳ `path` | string | File path |
| ↳ `sha` | string | Blob SHA | | ↳ `sha` | string | Blob SHA |
| ↳ `url` | string | API URL | | ↳ `url` | string | API URL |
| ↳ `git_url` | string | Git blob URL | | ↳ `git_url` | string | Git blob URL |
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | GitHub web URL |
| ↳ `score` | number | Search relevance score | | ↳ `score` | number | Search relevance score |
| ↳ `repository` | object | Repository containing the code | | ↳ `repository` | object | Repository containing the code |
| ↳ `id` | number | User ID | | ↳ `id` | number | Repository ID |
| ↳ `node_id` | string | GraphQL node ID | | ↳ `node_id` | string | GraphQL node ID |
| ↳ `name` | string | Repository name | | ↳ `name` | string | Repository name |
| ↳ `full_name` | string | Full name \(owner/repo\) | | ↳ `full_name` | string | Full name \(owner/repo\) |
| ↳ `private` | boolean | Whether repository is private | | ↳ `private` | boolean | Whether repository is private |
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | GitHub web URL |
| ↳ `description` | string | Repository description | | ↳ `description` | string | Repository description |
| ↳ `fork` | boolean | Whether this is a fork | | ↳ `fork` | boolean | Whether this is a fork |
| ↳ `url` | string | API URL | | ↳ `url` | string | API URL |
@@ -1583,29 +1583,6 @@ Search for code across GitHub repositories. Use qualifiers like repo:owner/name,
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | Profile page URL |
| ↳ `type` | string | User or Organization | | ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator | | ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `login` | string | Username |
| ↳ `avatar_url` | string | Avatar image URL |
| ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `id` | number | User ID |
| ↳ `node_id` | string | GraphQL node ID |
| ↳ `full_name` | string | Full name \(owner/repo\) |
| ↳ `private` | boolean | Whether repository is private |
| ↳ `description` | string | Repository description |
| ↳ `fork` | boolean | Whether this is a fork |
| ↳ `owner` | object | Repository owner |
| ↳ `login` | string | Username |
| ↳ `id` | number | User ID |
| ↳ `node_id` | string | GraphQL node ID |
| ↳ `avatar_url` | string | Avatar image URL |
| ↳ `url` | string | API URL |
| ↳ `html_url` | string | Profile page URL |
| ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `login` | string | Username |
| ↳ `avatar_url` | string | Avatar image URL |
| ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `text_matches` | array | Text matches showing context | | ↳ `text_matches` | array | Text matches showing context |
| ↳ `object_url` | string | Object URL | | ↳ `object_url` | string | Object URL |
| ↳ `object_type` | string | Object type | | ↳ `object_type` | string | Object type |
@@ -1614,17 +1591,6 @@ Search for code across GitHub repositories. Use qualifiers like repo:owner/name,
| ↳ `matches` | array | Match indices | | ↳ `matches` | array | Match indices |
| ↳ `text` | string | Matched text | | ↳ `text` | string | Matched text |
| ↳ `indices` | array | Start and end indices | | ↳ `indices` | array | Start and end indices |
| ↳ `text` | string | Matched text |
| ↳ `indices` | array | Start and end indices |
| ↳ `object_url` | string | Object URL |
| ↳ `object_type` | string | Object type |
| ↳ `property` | string | Property matched |
| ↳ `fragment` | string | Text fragment with match |
| ↳ `matches` | array | Match indices |
| ↳ `text` | string | Matched text |
| ↳ `indices` | array | Start and end indices |
| ↳ `text` | string | Matched text |
| ↳ `indices` | array | Start and end indices |
### `github_search_commits` ### `github_search_commits`
@@ -1648,23 +1614,20 @@ Search for commits across GitHub. Use qualifiers like repo:owner/name, author:us
| `total_count` | number | Total matching results | | `total_count` | number | Total matching results |
| `incomplete_results` | boolean | Whether results are incomplete | | `incomplete_results` | boolean | Whether results are incomplete |
| `items` | array | Array of commit objects from GitHub API | | `items` | array | Array of commit objects from GitHub API |
| ↳ `sha` | string | Parent SHA | | ↳ `sha` | string | Commit SHA |
| ↳ `node_id` | string | GraphQL node ID | | ↳ `node_id` | string | GraphQL node ID |
| ↳ `html_url` | string | Parent web URL | | ↳ `html_url` | string | Web URL |
| ↳ `url` | string | Parent API URL | | ↳ `url` | string | API URL |
| ↳ `comments_url` | string | Comments API URL | | ↳ `comments_url` | string | Comments API URL |
| ↳ `score` | number | Search relevance score | | ↳ `score` | number | Search relevance score |
| ↳ `commit` | object | Core commit data | | ↳ `commit` | object | Core commit data |
| ↳ `url` | string | Tree API URL | | ↳ `url` | string | Commit API URL |
| ↳ `message` | string | Commit message | | ↳ `message` | string | Commit message |
| ↳ `comment_count` | number | Number of comments | | ↳ `comment_count` | number | Number of comments |
| ↳ `author` | object | Git author | | ↳ `author` | object | Git author |
| ↳ `name` | string | Author name | | ↳ `name` | string | Author name |
| ↳ `email` | string | Author email | | ↳ `email` | string | Author email |
| ↳ `date` | string | Author date \(ISO 8601\) | | ↳ `date` | string | Author date \(ISO 8601\) |
| ↳ `name` | string | Committer name |
| ↳ `email` | string | Committer email |
| ↳ `date` | string | Commit date \(ISO 8601\) |
| ↳ `committer` | object | Git committer | | ↳ `committer` | object | Git committer |
| ↳ `name` | string | Committer name | | ↳ `name` | string | Committer name |
| ↳ `email` | string | Committer email | | ↳ `email` | string | Committer email |
@@ -1672,9 +1635,6 @@ Search for commits across GitHub. Use qualifiers like repo:owner/name, author:us
| ↳ `tree` | object | Tree object | | ↳ `tree` | object | Tree object |
| ↳ `sha` | string | Tree SHA | | ↳ `sha` | string | Tree SHA |
| ↳ `url` | string | Tree API URL | | ↳ `url` | string | Tree API URL |
| ↳ `sha` | string | Tree SHA |
| ↳ `message` | string | Commit message |
| ↳ `comment_count` | number | Number of comments |
| ↳ `author` | object | GitHub user \(author\) | | ↳ `author` | object | GitHub user \(author\) |
| ↳ `login` | string | Username | | ↳ `login` | string | Username |
| ↳ `id` | number | User ID | | ↳ `id` | number | User ID |
@@ -1684,9 +1644,6 @@ Search for commits across GitHub. Use qualifiers like repo:owner/name, author:us
| ↳ `html_url` | string | Profile URL | | ↳ `html_url` | string | Profile URL |
| ↳ `type` | string | User or Organization | | ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator | | ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `name` | string | Repository name |
| ↳ `email` | string | Committer email |
| ↳ `date` | string | Commit date \(ISO 8601\) |
| ↳ `committer` | object | GitHub user \(committer\) | | ↳ `committer` | object | GitHub user \(committer\) |
| ↳ `login` | string | Username | | ↳ `login` | string | Username |
| ↳ `id` | number | User ID | | ↳ `id` | number | User ID |
@@ -1696,38 +1653,13 @@ Search for commits across GitHub. Use qualifiers like repo:owner/name, author:us
| ↳ `html_url` | string | Profile URL | | ↳ `html_url` | string | Profile URL |
| ↳ `type` | string | User or Organization | | ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator | | ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `tree` | object | Tree object |
| ↳ `sha` | string | Tree SHA |
| ↳ `url` | string | Tree API URL |
| ↳ `login` | string | Username |
| ↳ `id` | number | User ID |
| ↳ `avatar_url` | string | Avatar image URL |
| ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `repository` | object | Repository containing the commit | | ↳ `repository` | object | Repository containing the commit |
| ↳ `id` | number | User ID | | ↳ `id` | number | Repository ID |
| ↳ `node_id` | string | GraphQL node ID | | ↳ `node_id` | string | GraphQL node ID |
| ↳ `name` | string | Repository name | | ↳ `name` | string | Repository name |
| ↳ `full_name` | string | Full name \(owner/repo\) | | ↳ `full_name` | string | Full name \(owner/repo\) |
| ↳ `private` | boolean | Whether repository is private | | ↳ `private` | boolean | Whether repository is private |
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | GitHub web URL |
| ↳ `description` | string | Repository description |
| ↳ `owner` | object | Repository owner |
| ↳ `login` | string | Username |
| ↳ `id` | number | User ID |
| ↳ `node_id` | string | GraphQL node ID |
| ↳ `avatar_url` | string | Avatar image URL |
| ↳ `url` | string | API URL |
| ↳ `html_url` | string | Profile page URL |
| ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `login` | string | Username |
| ↳ `avatar_url` | string | Avatar image URL |
| ↳ `url` | string | API URL |
| ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `full_name` | string | Full name \(owner/repo\) |
| ↳ `private` | boolean | Whether repository is private |
| ↳ `description` | string | Repository description | | ↳ `description` | string | Repository description |
| ↳ `owner` | object | Repository owner | | ↳ `owner` | object | Repository owner |
| ↳ `login` | string | Username | | ↳ `login` | string | Username |
@@ -1765,10 +1697,10 @@ Search for issues and pull requests across GitHub. Use qualifiers like repo:owne
| `total_count` | number | Total matching results | | `total_count` | number | Total matching results |
| `incomplete_results` | boolean | Whether results are incomplete | | `incomplete_results` | boolean | Whether results are incomplete |
| `items` | array | Array of issue/PR objects from GitHub API | | `items` | array | Array of issue/PR objects from GitHub API |
| ↳ `id` | number | Milestone ID | | ↳ `id` | number | Issue ID |
| ↳ `node_id` | string | GraphQL node ID | | ↳ `node_id` | string | GraphQL node ID |
| ↳ `number` | number | Milestone number | | ↳ `number` | number | Issue number |
| ↳ `title` | string | Milestone title | | ↳ `title` | string | Title |
| ↳ `state` | string | State \(open or closed\) | | ↳ `state` | string | State \(open or closed\) |
| ↳ `locked` | boolean | Whether issue is locked | | ↳ `locked` | boolean | Whether issue is locked |
| ↳ `html_url` | string | Web URL | | ↳ `html_url` | string | Web URL |
@@ -1790,10 +1722,6 @@ Search for issues and pull requests across GitHub. Use qualifiers like repo:owne
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | Profile page URL |
| ↳ `type` | string | User or Organization | | ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator | | ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `login` | string | Username |
| ↳ `avatar_url` | string | Avatar image URL |
| ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `labels` | array | Issue labels | | ↳ `labels` | array | Issue labels |
| ↳ `id` | number | Label ID | | ↳ `id` | number | Label ID |
| ↳ `node_id` | string | GraphQL node ID | | ↳ `node_id` | string | GraphQL node ID |
@@ -1802,10 +1730,6 @@ Search for issues and pull requests across GitHub. Use qualifiers like repo:owne
| ↳ `description` | string | Label description | | ↳ `description` | string | Label description |
| ↳ `color` | string | Hex color code | | ↳ `color` | string | Hex color code |
| ↳ `default` | boolean | Whether this is a default label | | ↳ `default` | boolean | Whether this is a default label |
| ↳ `name` | string | Label name |
| ↳ `description` | string | Milestone description |
| ↳ `color` | string | Hex color code |
| ↳ `default` | boolean | Whether this is a default label |
| ↳ `assignee` | object | Primary assignee | | ↳ `assignee` | object | Primary assignee |
| ↳ `login` | string | Username | | ↳ `login` | string | Username |
| ↳ `id` | number | User ID | | ↳ `id` | number | User ID |
@@ -1833,14 +1757,11 @@ Search for issues and pull requests across GitHub. Use qualifiers like repo:owne
| ↳ `state` | string | State \(open or closed\) | | ↳ `state` | string | State \(open or closed\) |
| ↳ `html_url` | string | Web URL | | ↳ `html_url` | string | Web URL |
| ↳ `due_on` | string | Due date | | ↳ `due_on` | string | Due date |
| ↳ `due_on` | string | Due date |
| ↳ `pull_request` | object | Pull request details \(if this is a PR\) | | ↳ `pull_request` | object | Pull request details \(if this is a PR\) |
| ↳ `url` | string | API URL | | ↳ `url` | string | API URL |
| ↳ `html_url` | string | Web URL | | ↳ `html_url` | string | Web URL |
| ↳ `diff_url` | string | Diff URL | | ↳ `diff_url` | string | Diff URL |
| ↳ `patch_url` | string | Patch URL | | ↳ `patch_url` | string | Patch URL |
| ↳ `diff_url` | string | Diff URL |
| ↳ `patch_url` | string | Patch URL |
### `github_search_repos` ### `github_search_repos`
@@ -1864,13 +1785,13 @@ Search for repositories across GitHub. Use qualifiers like language:python, star
| `total_count` | number | Total matching results | | `total_count` | number | Total matching results |
| `incomplete_results` | boolean | Whether results are incomplete | | `incomplete_results` | boolean | Whether results are incomplete |
| `items` | array | Array of repository objects from GitHub API | | `items` | array | Array of repository objects from GitHub API |
| ↳ `id` | number | User ID | | ↳ `id` | number | Repository ID |
| ↳ `node_id` | string | GraphQL node ID | | ↳ `node_id` | string | GraphQL node ID |
| ↳ `name` | string | License name | | ↳ `name` | string | Repository name |
| ↳ `full_name` | string | Full name \(owner/repo\) | | ↳ `full_name` | string | Full name \(owner/repo\) |
| ↳ `private` | boolean | Whether repository is private | | ↳ `private` | boolean | Whether repository is private |
| ↳ `description` | string | Repository description | | ↳ `description` | string | Repository description |
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | GitHub web URL |
| ↳ `url` | string | API URL | | ↳ `url` | string | API URL |
| ↳ `fork` | boolean | Whether this is a fork | | ↳ `fork` | boolean | Whether this is a fork |
| ↳ `created_at` | string | Creation timestamp | | ↳ `created_at` | string | Creation timestamp |
@@ -1889,8 +1810,6 @@ Search for repositories across GitHub. Use qualifiers like language:python, star
| ↳ `key` | string | License key \(e.g., mit\) | | ↳ `key` | string | License key \(e.g., mit\) |
| ↳ `name` | string | License name | | ↳ `name` | string | License name |
| ↳ `spdx_id` | string | SPDX identifier | | ↳ `spdx_id` | string | SPDX identifier |
| ↳ `key` | string | License key \(e.g., mit\) |
| ↳ `spdx_id` | string | SPDX identifier |
| ↳ `owner` | object | Repository owner | | ↳ `owner` | object | Repository owner |
| ↳ `login` | string | Username | | ↳ `login` | string | Username |
| ↳ `id` | number | User ID | | ↳ `id` | number | User ID |
@@ -1900,10 +1819,6 @@ Search for repositories across GitHub. Use qualifiers like language:python, star
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | Profile page URL |
| ↳ `type` | string | User or Organization | | ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator | | ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `login` | string | Username |
| ↳ `avatar_url` | string | Avatar image URL |
| ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator |
### `github_search_users` ### `github_search_users`
@@ -1969,22 +1884,19 @@ List commits in a repository with optional filtering by SHA, path, author, commi
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `items` | array | Array of commit objects from GitHub API | | `items` | array | Array of commit objects from GitHub API |
| ↳ `sha` | string | Parent SHA | | ↳ `sha` | string | Commit SHA |
| ↳ `node_id` | string | GraphQL node ID | | ↳ `node_id` | string | GraphQL node ID |
| ↳ `html_url` | string | Parent web URL | | ↳ `html_url` | string | Web URL |
| ↳ `url` | string | Parent API URL | | ↳ `url` | string | API URL |
| ↳ `comments_url` | string | Comments API URL | | ↳ `comments_url` | string | Comments API URL |
| ↳ `commit` | object | Core commit data | | ↳ `commit` | object | Core commit data |
| ↳ `url` | string | Tree API URL | | ↳ `url` | string | Commit API URL |
| ↳ `message` | string | Commit message | | ↳ `message` | string | Commit message |
| ↳ `comment_count` | number | Number of comments | | ↳ `comment_count` | number | Number of comments |
| ↳ `author` | object | Git author | | ↳ `author` | object | Git author |
| ↳ `name` | string | Author name | | ↳ `name` | string | Author name |
| ↳ `email` | string | Author email | | ↳ `email` | string | Author email |
| ↳ `date` | string | Author date \(ISO 8601\) | | ↳ `date` | string | Author date \(ISO 8601\) |
| ↳ `name` | string | Committer name |
| ↳ `email` | string | Committer email |
| ↳ `date` | string | Commit date \(ISO 8601\) |
| ↳ `committer` | object | Git committer | | ↳ `committer` | object | Git committer |
| ↳ `name` | string | Committer name | | ↳ `name` | string | Committer name |
| ↳ `email` | string | Committer email | | ↳ `email` | string | Committer email |
@@ -1992,18 +1904,11 @@ List commits in a repository with optional filtering by SHA, path, author, commi
| ↳ `tree` | object | Tree object | | ↳ `tree` | object | Tree object |
| ↳ `sha` | string | Tree SHA | | ↳ `sha` | string | Tree SHA |
| ↳ `url` | string | Tree API URL | | ↳ `url` | string | Tree API URL |
| ↳ `sha` | string | Tree SHA |
| ↳ `verification` | object | Signature verification | | ↳ `verification` | object | Signature verification |
| ↳ `verified` | boolean | Whether signature is verified | | ↳ `verified` | boolean | Whether signature is verified |
| ↳ `reason` | string | Verification reason | | ↳ `reason` | string | Verification reason |
| ↳ `signature` | string | GPG signature | | ↳ `signature` | string | GPG signature |
| ↳ `payload` | string | Signed payload | | ↳ `payload` | string | Signed payload |
| ↳ `verified` | boolean | Whether signature is verified |
| ↳ `reason` | string | Verification reason |
| ↳ `signature` | string | GPG signature |
| ↳ `payload` | string | Signed payload |
| ↳ `message` | string | Commit message |
| ↳ `comment_count` | number | Number of comments |
| ↳ `author` | object | GitHub user \(author\) | | ↳ `author` | object | GitHub user \(author\) |
| ↳ `login` | string | Username | | ↳ `login` | string | Username |
| ↳ `id` | number | User ID | | ↳ `id` | number | User ID |
@@ -2013,9 +1918,6 @@ List commits in a repository with optional filtering by SHA, path, author, commi
| ↳ `html_url` | string | Profile URL | | ↳ `html_url` | string | Profile URL |
| ↳ `type` | string | User or Organization | | ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator | | ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `name` | string | Committer name |
| ↳ `email` | string | Committer email |
| ↳ `date` | string | Commit date \(ISO 8601\) |
| ↳ `committer` | object | GitHub user \(committer\) | | ↳ `committer` | object | GitHub user \(committer\) |
| ↳ `login` | string | Username | | ↳ `login` | string | Username |
| ↳ `id` | number | User ID | | ↳ `id` | number | User ID |
@@ -2025,23 +1927,6 @@ List commits in a repository with optional filtering by SHA, path, author, commi
| ↳ `html_url` | string | Profile URL | | ↳ `html_url` | string | Profile URL |
| ↳ `type` | string | User or Organization | | ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator | | ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `tree` | object | Tree object |
| ↳ `sha` | string | Tree SHA |
| ↳ `url` | string | Tree API URL |
| ↳ `verification` | object | Signature verification |
| ↳ `verified` | boolean | Whether signature is verified |
| ↳ `reason` | string | Verification reason |
| ↳ `signature` | string | GPG signature |
| ↳ `payload` | string | Signed payload |
| ↳ `verified` | boolean | Whether signature is verified |
| ↳ `reason` | string | Verification reason |
| ↳ `signature` | string | GPG signature |
| ↳ `payload` | string | Signed payload |
| ↳ `login` | string | Username |
| ↳ `id` | number | User ID |
| ↳ `avatar_url` | string | Avatar URL |
| ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `parents` | array | Parent commits | | ↳ `parents` | array | Parent commits |
| ↳ `sha` | string | Parent SHA | | ↳ `sha` | string | Parent SHA |
| ↳ `url` | string | Parent API URL | | ↳ `url` | string | Parent API URL |
@@ -2071,16 +1956,13 @@ Get detailed information about a specific commit including files changed and sta
| `url` | string | API URL | | `url` | string | API URL |
| `comments_url` | string | Comments API URL | | `comments_url` | string | Comments API URL |
| `commit` | object | Core commit data | | `commit` | object | Core commit data |
| ↳ `url` | string | Tree API URL | | ↳ `url` | string | Commit API URL |
| ↳ `message` | string | Commit message | | ↳ `message` | string | Commit message |
| ↳ `comment_count` | number | Number of comments | | ↳ `comment_count` | number | Number of comments |
| ↳ `author` | object | Git author | | ↳ `author` | object | Git author |
| ↳ `name` | string | Author name | | ↳ `name` | string | Author name |
| ↳ `email` | string | Author email | | ↳ `email` | string | Author email |
| ↳ `date` | string | Author date \(ISO 8601\) | | ↳ `date` | string | Author date \(ISO 8601\) |
| ↳ `name` | string | Committer name |
| ↳ `email` | string | Committer email |
| ↳ `date` | string | Commit date \(ISO 8601\) |
| ↳ `committer` | object | Git committer | | ↳ `committer` | object | Git committer |
| ↳ `name` | string | Committer name | | ↳ `name` | string | Committer name |
| ↳ `email` | string | Committer email | | ↳ `email` | string | Committer email |
@@ -2088,16 +1970,11 @@ Get detailed information about a specific commit including files changed and sta
| ↳ `tree` | object | Tree object | | ↳ `tree` | object | Tree object |
| ↳ `sha` | string | Tree SHA | | ↳ `sha` | string | Tree SHA |
| ↳ `url` | string | Tree API URL | | ↳ `url` | string | Tree API URL |
| ↳ `sha` | string | Tree SHA |
| ↳ `verification` | object | Signature verification | | ↳ `verification` | object | Signature verification |
| ↳ `verified` | boolean | Whether signature is verified | | ↳ `verified` | boolean | Whether signature is verified |
| ↳ `reason` | string | Verification reason | | ↳ `reason` | string | Verification reason |
| ↳ `signature` | string | GPG signature | | ↳ `signature` | string | GPG signature |
| ↳ `payload` | string | Signed payload | | ↳ `payload` | string | Signed payload |
| ↳ `verified` | boolean | Whether signature is verified |
| ↳ `reason` | string | Verification reason |
| ↳ `signature` | string | GPG signature |
| ↳ `payload` | string | Signed payload |
| `author` | object | GitHub user \(author\) | | `author` | object | GitHub user \(author\) |
| ↳ `login` | string | Username | | ↳ `login` | string | Username |
| ↳ `id` | number | User ID | | ↳ `id` | number | User ID |
@@ -2167,7 +2044,6 @@ Compare two commits or branches to see the diff, commits between them, and chang
| ↳ `message` | string | Commit message | | ↳ `message` | string | Commit message |
| ↳ `author` | object | Git author \(name, email, date\) | | ↳ `author` | object | Git author \(name, email, date\) |
| ↳ `committer` | object | Git committer \(name, email, date\) | | ↳ `committer` | object | Git committer \(name, email, date\) |
| ↳ `message` | string | Commit message |
| ↳ `author` | object | GitHub user \(author\) | | ↳ `author` | object | GitHub user \(author\) |
| ↳ `committer` | object | GitHub user \(committer\) | | ↳ `committer` | object | GitHub user \(committer\) |
| `merge_base_commit` | object | Merge base commit object | | `merge_base_commit` | object | Merge base commit object |
@@ -2180,7 +2056,6 @@ Compare two commits or branches to see the diff, commits between them, and chang
| ↳ `message` | string | Commit message | | ↳ `message` | string | Commit message |
| ↳ `author` | object | Git author \(name, email, date\) | | ↳ `author` | object | Git author \(name, email, date\) |
| ↳ `committer` | object | Git committer \(name, email, date\) | | ↳ `committer` | object | Git committer \(name, email, date\) |
| ↳ `message` | string | Commit message |
| ↳ `author` | object | GitHub user | | ↳ `author` | object | GitHub user |
| ↳ `committer` | object | GitHub user | | ↳ `committer` | object | GitHub user |
| `files` | array | Changed files \(diff entries\) | | `files` | array | Changed files \(diff entries\) |
@@ -2271,13 +2146,6 @@ Get a gist by ID including its file contents
| `comments_url` | string | Comments API URL | | `comments_url` | string | Comments API URL |
| `truncated` | boolean | Whether content is truncated | | `truncated` | boolean | Whether content is truncated |
| `files` | object | Files in the gist \(keyed by filename\) | | `files` | object | Files in the gist \(keyed by filename\) |
| ↳ `filename` | string | File name |
| ↳ `type` | string | MIME type |
| ↳ `language` | string | Programming language |
| ↳ `raw_url` | string | Raw file URL |
| ↳ `size` | number | File size in bytes |
| ↳ `truncated` | boolean | Whether content is truncated |
| ↳ `content` | string | File content |
| `owner` | object | Gist owner | | `owner` | object | Gist owner |
| ↳ `login` | string | Username | | ↳ `login` | string | Username |
| ↳ `id` | number | User ID | | ↳ `id` | number | User ID |
@@ -2307,10 +2175,10 @@ List gists for a user or the authenticated user
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `items` | array | Array of gist objects from GitHub API | | `items` | array | Array of gist objects from GitHub API |
| ↳ `id` | number | User ID | | ↳ `id` | string | Gist ID |
| ↳ `node_id` | string | GraphQL node ID | | ↳ `node_id` | string | GraphQL node ID |
| ↳ `url` | string | API URL | | ↳ `url` | string | API URL |
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | Web URL |
| ↳ `forks_url` | string | Forks API URL | | ↳ `forks_url` | string | Forks API URL |
| ↳ `commits_url` | string | Commits API URL | | ↳ `commits_url` | string | Commits API URL |
| ↳ `git_pull_url` | string | Git pull URL | | ↳ `git_pull_url` | string | Git pull URL |
@@ -2332,10 +2200,6 @@ List gists for a user or the authenticated user
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | Profile page URL |
| ↳ `type` | string | User or Organization | | ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator | | ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `login` | string | Username |
| ↳ `avatar_url` | string | Avatar image URL |
| ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator |
| `count` | number | Number of gists returned | | `count` | number | Number of gists returned |
### `github_update_gist` ### `github_update_gist`
@@ -2503,14 +2367,13 @@ Fork a repository to your account or an organization
| ↳ `type` | string | User or Organization | | ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator | | ↳ `site_admin` | boolean | GitHub staff indicator |
| `parent` | object | Parent repository \(source of the fork\) | | `parent` | object | Parent repository \(source of the fork\) |
| ↳ `id` | number | User ID | | ↳ `id` | number | Repository ID |
| ↳ `full_name` | string | Full name | | ↳ `full_name` | string | Full name |
| ↳ `html_url` | string | Web URL | | ↳ `html_url` | string | Web URL |
| ↳ `description` | string | Description | | ↳ `description` | string | Description |
| ↳ `owner` | object | Parent owner | | ↳ `owner` | object | Parent owner |
| ↳ `login` | string | Username | | ↳ `login` | string | Username |
| ↳ `id` | number | User ID | | ↳ `id` | number | User ID |
| ↳ `login` | string | Username |
| `source` | object | Source repository \(ultimate origin\) | | `source` | object | Source repository \(ultimate origin\) |
| ↳ `id` | number | Repository ID | | ↳ `id` | number | Repository ID |
| ↳ `full_name` | string | Full name | | ↳ `full_name` | string | Full name |
@@ -2536,13 +2399,13 @@ List forks of a repository
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `items` | array | Array of fork repository objects from GitHub API | | `items` | array | Array of fork repository objects from GitHub API |
| ↳ `id` | number | User ID | | ↳ `id` | number | Repository ID |
| ↳ `node_id` | string | GraphQL node ID | | ↳ `node_id` | string | GraphQL node ID |
| ↳ `name` | string | Repository name | | ↳ `name` | string | Repository name |
| ↳ `full_name` | string | Full name \(owner/repo\) | | ↳ `full_name` | string | Full name \(owner/repo\) |
| ↳ `private` | boolean | Whether repository is private | | ↳ `private` | boolean | Whether repository is private |
| ↳ `description` | string | Repository description | | ↳ `description` | string | Repository description |
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | GitHub web URL |
| ↳ `url` | string | API URL | | ↳ `url` | string | API URL |
| ↳ `fork` | boolean | Whether this is a fork | | ↳ `fork` | boolean | Whether this is a fork |
| ↳ `created_at` | string | Creation timestamp | | ↳ `created_at` | string | Creation timestamp |
@@ -2567,10 +2430,6 @@ List forks of a repository
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | Profile page URL |
| ↳ `type` | string | User or Organization | | ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator | | ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `login` | string | Username |
| ↳ `avatar_url` | string | Avatar image URL |
| ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator |
| `count` | number | Number of forks returned | | `count` | number | Number of forks returned |
### `github_create_milestone` ### `github_create_milestone`
@@ -2667,14 +2526,14 @@ List milestones in a repository
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `items` | array | Array of milestone objects from GitHub API | | `items` | array | Array of milestone objects from GitHub API |
| ↳ `id` | number | User ID | | ↳ `id` | number | Milestone ID |
| ↳ `node_id` | string | GraphQL node ID | | ↳ `node_id` | string | GraphQL node ID |
| ↳ `number` | number | Milestone number | | ↳ `number` | number | Milestone number |
| ↳ `title` | string | Milestone title | | ↳ `title` | string | Milestone title |
| ↳ `description` | string | Milestone description | | ↳ `description` | string | Milestone description |
| ↳ `state` | string | State \(open or closed\) | | ↳ `state` | string | State \(open or closed\) |
| ↳ `url` | string | API URL | | ↳ `url` | string | API URL |
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | GitHub web URL |
| ↳ `labels_url` | string | Labels API URL | | ↳ `labels_url` | string | Labels API URL |
| ↳ `due_on` | string | Due date \(ISO 8601\) | | ↳ `due_on` | string | Due date \(ISO 8601\) |
| ↳ `open_issues` | number | Number of open issues | | ↳ `open_issues` | number | Number of open issues |
@@ -2691,10 +2550,6 @@ List milestones in a repository
| ↳ `html_url` | string | Profile page URL | | ↳ `html_url` | string | Profile page URL |
| ↳ `type` | string | User or Organization | | ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator | | ↳ `site_admin` | boolean | GitHub staff indicator |
| ↳ `login` | string | Username |
| ↳ `avatar_url` | string | Avatar image URL |
| ↳ `type` | string | User or Organization |
| ↳ `site_admin` | boolean | GitHub staff indicator |
| `count` | number | Number of milestones returned | | `count` | number | Number of milestones returned |
### `github_update_milestone` ### `github_update_milestone`

View File

@@ -139,25 +139,10 @@ Apply multiple updates to a form (add items, update info, change settings, etc.)
| ↳ `title` | string | The form title visible to responders | | ↳ `title` | string | The form title visible to responders |
| ↳ `description` | string | The form description | | ↳ `description` | string | The form description |
| ↳ `documentTitle` | string | The document title visible in Drive | | ↳ `documentTitle` | string | The document title visible in Drive |
| ↳ `title` | string | Item title |
| ↳ `description` | string | Item description |
| ↳ `documentTitle` | string | The document title visible in Drive |
| ↳ `settings` | object | Form settings | | ↳ `settings` | object | Form settings |
| ↳ `quizSettings` | object | Quiz settings | | ↳ `quizSettings` | object | Quiz settings |
| ↳ `isQuiz` | boolean | Whether the form is a quiz | | ↳ `isQuiz` | boolean | Whether the form is a quiz |
| ↳ `isQuiz` | boolean | Whether the form is a quiz |
| ↳ `emailCollectionType` | string | Email collection type | | ↳ `emailCollectionType` | string | Email collection type |
| ↳ `quizSettings` | object | Quiz settings |
| ↳ `isQuiz` | boolean | Whether the form is a quiz |
| ↳ `isQuiz` | boolean | Whether the form is a quiz |
| ↳ `emailCollectionType` | string | Email collection type |
| ↳ `itemId` | string | Item ID |
| ↳ `questionItem` | json | Question item configuration |
| ↳ `questionGroupItem` | json | Question group configuration |
| ↳ `pageBreakItem` | json | Page break configuration |
| ↳ `textItem` | json | Text item configuration |
| ↳ `imageItem` | json | Image item configuration |
| ↳ `videoItem` | json | Video item configuration |
| ↳ `revisionId` | string | The revision ID of the form | | ↳ `revisionId` | string | The revision ID of the form |
| ↳ `responderUri` | string | The URI to share with responders | | ↳ `responderUri` | string | The URI to share with responders |
| ↳ `linkedSheetId` | string | The ID of the linked Google Sheet | | ↳ `linkedSheetId` | string | The ID of the linked Google Sheet |
@@ -165,13 +150,6 @@ Apply multiple updates to a form (add items, update info, change settings, etc.)
| ↳ `publishState` | object | Current publish state | | ↳ `publishState` | object | Current publish state |
| ↳ `isPublished` | boolean | Whether the form is published | | ↳ `isPublished` | boolean | Whether the form is published |
| ↳ `isAcceptingResponses` | boolean | Whether the form is accepting responses | | ↳ `isAcceptingResponses` | boolean | Whether the form is accepting responses |
| ↳ `isPublished` | boolean | Whether the form is published |
| ↳ `isAcceptingResponses` | boolean | Whether the form is accepting responses |
| ↳ `publishState` | object | Current publish state |
| ↳ `isPublished` | boolean | Whether the form is published |
| ↳ `isAcceptingResponses` | boolean | Whether the form is accepting responses |
| ↳ `isPublished` | boolean | Whether the form is published |
| ↳ `isAcceptingResponses` | boolean | Whether the form is accepting responses |
### `google_forms_set_publish_settings` ### `google_forms_set_publish_settings`
@@ -194,8 +172,6 @@ Update the publish settings of a form (publish/unpublish, accept responses)
| ↳ `publishState` | object | The publish state | | ↳ `publishState` | object | The publish state |
| ↳ `isPublished` | boolean | Whether the form is published | | ↳ `isPublished` | boolean | Whether the form is published |
| ↳ `isAcceptingResponses` | boolean | Whether the form accepts responses | | ↳ `isAcceptingResponses` | boolean | Whether the form accepts responses |
| ↳ `isPublished` | boolean | Whether the form is published |
| ↳ `isAcceptingResponses` | boolean | Whether the form accepts responses |
### `google_forms_create_watch` ### `google_forms_create_watch`

View File

@@ -57,8 +57,6 @@ Read content from a Google Slides presentation
| ↳ `pageSize` | object | Presentation page size | | ↳ `pageSize` | object | Presentation page size |
| ↳ `width` | json | Page width as a Dimension object | | ↳ `width` | json | Page width as a Dimension object |
| ↳ `height` | json | Page height as a Dimension object | | ↳ `height` | json | Page height as a Dimension object |
| ↳ `width` | json | Page width as a Dimension object |
| ↳ `height` | json | Page height as a Dimension object |
| ↳ `mimeType` | string | The mime type of the presentation | | ↳ `mimeType` | string | The mime type of the presentation |
| ↳ `url` | string | URL to open the presentation | | ↳ `url` | string | URL to open the presentation |

View File

@@ -60,8 +60,5 @@ Generate completions using Hugging Face Inference API
| ↳ `prompt_tokens` | number | Number of tokens in the prompt | | ↳ `prompt_tokens` | number | Number of tokens in the prompt |
| ↳ `completion_tokens` | number | Number of tokens in the completion | | ↳ `completion_tokens` | number | Number of tokens in the completion |
| ↳ `total_tokens` | number | Total number of tokens used | | ↳ `total_tokens` | number | Total number of tokens used |
| ↳ `prompt_tokens` | number | Number of tokens in the prompt |
| ↳ `completion_tokens` | number | Number of tokens in the completion |
| ↳ `total_tokens` | number | Total number of tokens used |

View File

@@ -62,6 +62,5 @@ Generate images using OpenAI
| ↳ `image` | string | Base64 encoded image data | | ↳ `image` | string | Base64 encoded image data |
| ↳ `metadata` | object | Image generation metadata | | ↳ `metadata` | object | Image generation metadata |
| ↳ `model` | string | Model used for image generation | | ↳ `model` | string | Model used for image generation |
| ↳ `model` | string | Model used for image generation |

View File

@@ -57,8 +57,8 @@ List incidents from incident.io. Returns a list of incidents with their details
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `incidents` | array | List of incidents | | `incidents` | array | List of incidents |
| ↳ `id` | string | Type ID | | ↳ `id` | string | Incident ID |
| ↳ `name` | string | Type name | | ↳ `name` | string | Incident name |
| ↳ `summary` | string | Brief summary of the incident | | ↳ `summary` | string | Brief summary of the incident |
| ↳ `description` | string | Detailed description of the incident | | ↳ `description` | string | Detailed description of the incident |
| ↳ `mode` | string | Incident mode \(e.g., standard, retrospective\) | | ↳ `mode` | string | Incident mode \(e.g., standard, retrospective\) |
@@ -67,12 +67,10 @@ List incidents from incident.io. Returns a list of incidents with their details
| ↳ `id` | string | Severity ID | | ↳ `id` | string | Severity ID |
| ↳ `name` | string | Severity name | | ↳ `name` | string | Severity name |
| ↳ `rank` | number | Severity rank | | ↳ `rank` | number | Severity rank |
| ↳ `rank` | number | Severity rank |
| ↳ `status` | object | Current status of the incident | | ↳ `status` | object | Current status of the incident |
| ↳ `id` | string | Status ID | | ↳ `id` | string | Status ID |
| ↳ `name` | string | Status name | | ↳ `name` | string | Status name |
| ↳ `category` | string | Status category | | ↳ `category` | string | Status category |
| ↳ `category` | string | Status category |
| ↳ `incident_type` | object | Type of the incident | | ↳ `incident_type` | object | Type of the incident |
| ↳ `id` | string | Type ID | | ↳ `id` | string | Type ID |
| ↳ `name` | string | Type name | | ↳ `name` | string | Type name |
@@ -109,8 +107,8 @@ Create a new incident in incident.io. Requires idempotency_key, severity_id, and
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `incident` | object | The created incident object | | `incident` | object | The created incident object |
| ↳ `id` | string | Type ID | | ↳ `id` | string | Incident ID |
| ↳ `name` | string | Type name | | ↳ `name` | string | Incident name |
| ↳ `summary` | string | Brief summary of the incident | | ↳ `summary` | string | Brief summary of the incident |
| ↳ `description` | string | Detailed description of the incident | | ↳ `description` | string | Detailed description of the incident |
| ↳ `mode` | string | Incident mode \(e.g., standard, retrospective\) | | ↳ `mode` | string | Incident mode \(e.g., standard, retrospective\) |
@@ -119,12 +117,10 @@ Create a new incident in incident.io. Requires idempotency_key, severity_id, and
| ↳ `id` | string | Severity ID | | ↳ `id` | string | Severity ID |
| ↳ `name` | string | Severity name | | ↳ `name` | string | Severity name |
| ↳ `rank` | number | Severity rank | | ↳ `rank` | number | Severity rank |
| ↳ `rank` | number | Severity rank |
| ↳ `status` | object | Current status of the incident | | ↳ `status` | object | Current status of the incident |
| ↳ `id` | string | Status ID | | ↳ `id` | string | Status ID |
| ↳ `name` | string | Status name | | ↳ `name` | string | Status name |
| ↳ `category` | string | Status category | | ↳ `category` | string | Status category |
| ↳ `category` | string | Status category |
| ↳ `incident_type` | object | Type of the incident | | ↳ `incident_type` | object | Type of the incident |
| ↳ `id` | string | Type ID | | ↳ `id` | string | Type ID |
| ↳ `name` | string | Type name | | ↳ `name` | string | Type name |
@@ -151,8 +147,8 @@ Retrieve detailed information about a specific incident from incident.io by its
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `incident` | object | Detailed incident information | | `incident` | object | Detailed incident information |
| ↳ `id` | string | Type ID | | ↳ `id` | string | Incident ID |
| ↳ `name` | string | Type name | | ↳ `name` | string | Incident name |
| ↳ `summary` | string | Brief summary of the incident | | ↳ `summary` | string | Brief summary of the incident |
| ↳ `description` | string | Detailed description of the incident | | ↳ `description` | string | Detailed description of the incident |
| ↳ `mode` | string | Incident mode \(e.g., standard, retrospective\) | | ↳ `mode` | string | Incident mode \(e.g., standard, retrospective\) |
@@ -162,12 +158,10 @@ Retrieve detailed information about a specific incident from incident.io by its
| ↳ `id` | string | Severity ID | | ↳ `id` | string | Severity ID |
| ↳ `name` | string | Severity name | | ↳ `name` | string | Severity name |
| ↳ `rank` | number | Severity rank | | ↳ `rank` | number | Severity rank |
| ↳ `rank` | number | Severity rank |
| ↳ `status` | object | Current status of the incident | | ↳ `status` | object | Current status of the incident |
| ↳ `id` | string | Status ID | | ↳ `id` | string | Status ID |
| ↳ `name` | string | Status name | | ↳ `name` | string | Status name |
| ↳ `category` | string | Status category | | ↳ `category` | string | Status category |
| ↳ `category` | string | Status category |
| ↳ `incident_type` | object | Type of the incident | | ↳ `incident_type` | object | Type of the incident |
| ↳ `id` | string | Type ID | | ↳ `id` | string | Type ID |
| ↳ `name` | string | Type name | | ↳ `name` | string | Type name |
@@ -202,8 +196,8 @@ Update an existing incident in incident.io. Can update name, summary, severity,
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `incident` | object | The updated incident object | | `incident` | object | The updated incident object |
| ↳ `id` | string | Type ID | | ↳ `id` | string | Incident ID |
| ↳ `name` | string | Type name | | ↳ `name` | string | Incident name |
| ↳ `summary` | string | Brief summary of the incident | | ↳ `summary` | string | Brief summary of the incident |
| ↳ `description` | string | Detailed description of the incident | | ↳ `description` | string | Detailed description of the incident |
| ↳ `mode` | string | Incident mode \(e.g., standard, retrospective\) | | ↳ `mode` | string | Incident mode \(e.g., standard, retrospective\) |
@@ -212,12 +206,10 @@ Update an existing incident in incident.io. Can update name, summary, severity,
| ↳ `id` | string | Severity ID | | ↳ `id` | string | Severity ID |
| ↳ `name` | string | Severity name | | ↳ `name` | string | Severity name |
| ↳ `rank` | number | Severity rank | | ↳ `rank` | number | Severity rank |
| ↳ `rank` | number | Severity rank |
| ↳ `status` | object | Current status of the incident | | ↳ `status` | object | Current status of the incident |
| ↳ `id` | string | Status ID | | ↳ `id` | string | Status ID |
| ↳ `name` | string | Status name | | ↳ `name` | string | Status name |
| ↳ `category` | string | Status category | | ↳ `category` | string | Status category |
| ↳ `category` | string | Status category |
| ↳ `incident_type` | object | Type of the incident | | ↳ `incident_type` | object | Type of the incident |
| ↳ `id` | string | Type ID | | ↳ `id` | string | Type ID |
| ↳ `name` | string | Type name | | ↳ `name` | string | Type name |
@@ -245,14 +237,12 @@ List actions from incident.io. Optionally filter by incident ID.
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `actions` | array | List of actions | | `actions` | array | List of actions |
| ↳ `id` | string | User ID | | ↳ `id` | string | Action ID |
| ↳ `description` | string | Action description | | ↳ `description` | string | Action description |
| ↳ `assignee` | object | Assigned user | | ↳ `assignee` | object | Assigned user |
| ↳ `id` | string | User ID | | ↳ `id` | string | User ID |
| ↳ `name` | string | User name | | ↳ `name` | string | User name |
| ↳ `email` | string | User email | | ↳ `email` | string | User email |
| ↳ `name` | string | User name |
| ↳ `email` | string | User email |
| ↳ `status` | string | Action status | | ↳ `status` | string | Action status |
| ↳ `due_at` | string | Due date/time | | ↳ `due_at` | string | Due date/time |
| ↳ `created_at` | string | Creation timestamp | | ↳ `created_at` | string | Creation timestamp |
@@ -267,9 +257,6 @@ List actions from incident.io. Optionally filter by incident ID.
| ↳ `provider` | string | Issue tracking provider \(e.g., Jira, Linear\) | | ↳ `provider` | string | Issue tracking provider \(e.g., Jira, Linear\) |
| ↳ `issue_name` | string | Issue identifier | | ↳ `issue_name` | string | Issue identifier |
| ↳ `issue_permalink` | string | URL to the external issue | | ↳ `issue_permalink` | string | URL to the external issue |
| ↳ `provider` | string | Issue tracking provider \(e.g., Jira, Linear\) |
| ↳ `issue_name` | string | Issue identifier |
| ↳ `issue_permalink` | string | URL to the external issue |
### `incidentio_actions_show` ### `incidentio_actions_show`
@@ -287,14 +274,12 @@ Get detailed information about a specific action from incident.io.
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `action` | object | Action details | | `action` | object | Action details |
| ↳ `id` | string | User ID | | ↳ `id` | string | Action ID |
| ↳ `description` | string | Action description | | ↳ `description` | string | Action description |
| ↳ `assignee` | object | Assigned user | | ↳ `assignee` | object | Assigned user |
| ↳ `id` | string | User ID | | ↳ `id` | string | User ID |
| ↳ `name` | string | User name | | ↳ `name` | string | User name |
| ↳ `email` | string | User email | | ↳ `email` | string | User email |
| ↳ `name` | string | User name |
| ↳ `email` | string | User email |
| ↳ `status` | string | Action status | | ↳ `status` | string | Action status |
| ↳ `due_at` | string | Due date/time | | ↳ `due_at` | string | Due date/time |
| ↳ `created_at` | string | Creation timestamp | | ↳ `created_at` | string | Creation timestamp |
@@ -309,9 +294,6 @@ Get detailed information about a specific action from incident.io.
| ↳ `provider` | string | Issue tracking provider \(e.g., Jira, Linear\) | | ↳ `provider` | string | Issue tracking provider \(e.g., Jira, Linear\) |
| ↳ `issue_name` | string | Issue identifier | | ↳ `issue_name` | string | Issue identifier |
| ↳ `issue_permalink` | string | URL to the external issue | | ↳ `issue_permalink` | string | URL to the external issue |
| ↳ `provider` | string | Issue tracking provider \(e.g., Jira, Linear\) |
| ↳ `issue_name` | string | Issue identifier |
| ↳ `issue_permalink` | string | URL to the external issue |
### `incidentio_follow_ups_list` ### `incidentio_follow_ups_list`
@@ -330,22 +312,19 @@ List follow-ups from incident.io. Optionally filter by incident ID.
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `follow_ups` | array | List of follow-ups | | `follow_ups` | array | List of follow-ups |
| ↳ `id` | string | User ID | | ↳ `id` | string | Follow-up ID |
| ↳ `title` | string | Follow-up title | | ↳ `title` | string | Follow-up title |
| ↳ `description` | string | Priority description | | ↳ `description` | string | Follow-up description |
| ↳ `assignee` | object | Assigned user | | ↳ `assignee` | object | Assigned user |
| ↳ `id` | string | User ID | | ↳ `id` | string | User ID |
| ↳ `name` | string | User name | | ↳ `name` | string | User name |
| ↳ `email` | string | User email | | ↳ `email` | string | User email |
| ↳ `name` | string | User name |
| ↳ `email` | string | User email |
| ↳ `status` | string | Follow-up status | | ↳ `status` | string | Follow-up status |
| ↳ `priority` | object | Follow-up priority | | ↳ `priority` | object | Follow-up priority |
| ↳ `id` | string | Priority ID | | ↳ `id` | string | Priority ID |
| ↳ `name` | string | Priority name | | ↳ `name` | string | Priority name |
| ↳ `description` | string | Priority description | | ↳ `description` | string | Priority description |
| ↳ `rank` | number | Priority rank | | ↳ `rank` | number | Priority rank |
| ↳ `rank` | number | Priority rank |
| ↳ `created_at` | string | Creation timestamp | | ↳ `created_at` | string | Creation timestamp |
| ↳ `updated_at` | string | Last update timestamp | | ↳ `updated_at` | string | Last update timestamp |
| ↳ `incident_id` | string | Associated incident ID | | ↳ `incident_id` | string | Associated incident ID |
@@ -359,9 +338,6 @@ List follow-ups from incident.io. Optionally filter by incident ID.
| ↳ `provider` | string | External provider name | | ↳ `provider` | string | External provider name |
| ↳ `issue_name` | string | External issue name or ID | | ↳ `issue_name` | string | External issue name or ID |
| ↳ `issue_permalink` | string | Permalink to external issue | | ↳ `issue_permalink` | string | Permalink to external issue |
| ↳ `provider` | string | External provider name |
| ↳ `issue_name` | string | External issue name or ID |
| ↳ `issue_permalink` | string | Permalink to external issue |
### `incidentio_follow_ups_show` ### `incidentio_follow_ups_show`
@@ -379,22 +355,19 @@ Get detailed information about a specific follow-up from incident.io.
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `follow_up` | object | Follow-up details | | `follow_up` | object | Follow-up details |
| ↳ `id` | string | User ID | | ↳ `id` | string | Follow-up ID |
| ↳ `title` | string | Follow-up title | | ↳ `title` | string | Follow-up title |
| ↳ `description` | string | Priority description | | ↳ `description` | string | Follow-up description |
| ↳ `assignee` | object | Assigned user | | ↳ `assignee` | object | Assigned user |
| ↳ `id` | string | User ID | | ↳ `id` | string | User ID |
| ↳ `name` | string | User name | | ↳ `name` | string | User name |
| ↳ `email` | string | User email | | ↳ `email` | string | User email |
| ↳ `name` | string | User name |
| ↳ `email` | string | User email |
| ↳ `status` | string | Follow-up status | | ↳ `status` | string | Follow-up status |
| ↳ `priority` | object | Follow-up priority | | ↳ `priority` | object | Follow-up priority |
| ↳ `id` | string | Priority ID | | ↳ `id` | string | Priority ID |
| ↳ `name` | string | Priority name | | ↳ `name` | string | Priority name |
| ↳ `description` | string | Priority description | | ↳ `description` | string | Priority description |
| ↳ `rank` | number | Priority rank | | ↳ `rank` | number | Priority rank |
| ↳ `rank` | number | Priority rank |
| ↳ `created_at` | string | Creation timestamp | | ↳ `created_at` | string | Creation timestamp |
| ↳ `updated_at` | string | Last update timestamp | | ↳ `updated_at` | string | Last update timestamp |
| ↳ `incident_id` | string | Associated incident ID | | ↳ `incident_id` | string | Associated incident ID |
@@ -408,9 +381,6 @@ Get detailed information about a specific follow-up from incident.io.
| ↳ `provider` | string | External provider name | | ↳ `provider` | string | External provider name |
| ↳ `issue_name` | string | External issue name or ID | | ↳ `issue_name` | string | External issue name or ID |
| ↳ `issue_permalink` | string | Permalink to external issue | | ↳ `issue_permalink` | string | Permalink to external issue |
| ↳ `provider` | string | External provider name |
| ↳ `issue_name` | string | External issue name or ID |
| ↳ `issue_permalink` | string | Permalink to external issue |
### `incidentio_users_list` ### `incidentio_users_list`
@@ -1089,25 +1059,21 @@ List all updates for a specific incident in incident.io
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `incident_updates` | array | List of incident updates | | `incident_updates` | array | List of incident updates |
| ↳ `id` | string | User ID | | ↳ `id` | string | The update ID |
| ↳ `incident_id` | string | The incident ID | | ↳ `incident_id` | string | The incident ID |
| ↳ `message` | string | The update message | | ↳ `message` | string | The update message |
| ↳ `new_severity` | object | New severity if changed | | ↳ `new_severity` | object | New severity if changed |
| ↳ `id` | string | Severity ID | | ↳ `id` | string | Severity ID |
| ↳ `name` | string | Severity name | | ↳ `name` | string | Severity name |
| ↳ `rank` | number | Severity rank | | ↳ `rank` | number | Severity rank |
| ↳ `name` | string | User name |
| ↳ `rank` | number | Severity rank |
| ↳ `new_status` | object | New status if changed | | ↳ `new_status` | object | New status if changed |
| ↳ `id` | string | Status ID | | ↳ `id` | string | Status ID |
| ↳ `name` | string | Status name | | ↳ `name` | string | Status name |
| ↳ `category` | string | Status category | | ↳ `category` | string | Status category |
| ↳ `category` | string | Status category |
| ↳ `updater` | object | User who created the update | | ↳ `updater` | object | User who created the update |
| ↳ `id` | string | User ID | | ↳ `id` | string | User ID |
| ↳ `name` | string | User name | | ↳ `name` | string | User name |
| ↳ `email` | string | User email | | ↳ `email` | string | User email |
| ↳ `email` | string | User email |
| ↳ `created_at` | string | When the update was created | | ↳ `created_at` | string | When the update was created |
| ↳ `updated_at` | string | When the update was last modified | | ↳ `updated_at` | string | When the update was last modified |
| `pagination_meta` | object | Pagination information | | `pagination_meta` | object | Pagination information |
@@ -1134,14 +1100,12 @@ List all entries for a specific schedule in incident.io
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `schedule_entries` | array | List of schedule entries | | `schedule_entries` | array | List of schedule entries |
| ↳ `id` | string | User ID | | ↳ `id` | string | The entry ID |
| ↳ `schedule_id` | string | The schedule ID | | ↳ `schedule_id` | string | The schedule ID |
| ↳ `user` | object | User assigned to this entry | | ↳ `user` | object | User assigned to this entry |
| ↳ `id` | string | User ID | | ↳ `id` | string | User ID |
| ↳ `name` | string | User name | | ↳ `name` | string | User name |
| ↳ `email` | string | User email | | ↳ `email` | string | User email |
| ↳ `name` | string | User name |
| ↳ `email` | string | User email |
| ↳ `start_at` | string | When the entry starts | | ↳ `start_at` | string | When the entry starts |
| ↳ `end_at` | string | When the entry ends | | ↳ `end_at` | string | When the entry ends |
| ↳ `layer_id` | string | The schedule layer ID | | ↳ `layer_id` | string | The schedule layer ID |
@@ -1174,15 +1138,13 @@ Create a new schedule override in incident.io
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `override` | object | The created schedule override | | `override` | object | The created schedule override |
| ↳ `id` | string | User ID | | ↳ `id` | string | The override ID |
| ↳ `rotation_id` | string | The rotation ID | | ↳ `rotation_id` | string | The rotation ID |
| ↳ `schedule_id` | string | The schedule ID | | ↳ `schedule_id` | string | The schedule ID |
| ↳ `user` | object | User assigned to this override | | ↳ `user` | object | User assigned to this override |
| ↳ `id` | string | User ID | | ↳ `id` | string | User ID |
| ↳ `name` | string | User name | | ↳ `name` | string | User name |
| ↳ `email` | string | User email | | ↳ `email` | string | User email |
| ↳ `name` | string | User name |
| ↳ `email` | string | User email |
| ↳ `start_at` | string | When the override starts | | ↳ `start_at` | string | When the override starts |
| ↳ `end_at` | string | When the override ends | | ↳ `end_at` | string | When the override ends |
| ↳ `created_at` | string | When the override was created | | ↳ `created_at` | string | When the override was created |
@@ -1206,7 +1168,7 @@ Create a new escalation path in incident.io
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `escalation_path` | object | The created escalation path | | `escalation_path` | object | The created escalation path |
| ↳ `id` | string | Target ID | | ↳ `id` | string | The escalation path ID |
| ↳ `name` | string | The escalation path name | | ↳ `name` | string | The escalation path name |
| ↳ `path` | array | Array of escalation levels | | ↳ `path` | array | Array of escalation levels |
| ↳ `targets` | array | Targets for this level | | ↳ `targets` | array | Targets for this level |
@@ -1215,30 +1177,11 @@ Create a new escalation path in incident.io
| ↳ `schedule_id` | string | Schedule ID if type is schedule | | ↳ `schedule_id` | string | Schedule ID if type is schedule |
| ↳ `user_id` | string | User ID if type is user | | ↳ `user_id` | string | User ID if type is user |
| ↳ `urgency` | string | Urgency level | | ↳ `urgency` | string | Urgency level |
| ↳ `id` | string | Target ID |
| ↳ `type` | string | Target type |
| ↳ `schedule_id` | string | Schedule ID if type is schedule |
| ↳ `user_id` | string | User ID if type is user |
| ↳ `urgency` | string | Urgency level |
| ↳ `time_to_ack_seconds` | number | Time to acknowledge in seconds | | ↳ `time_to_ack_seconds` | number | Time to acknowledge in seconds |
| ↳ `targets` | array | Targets for this level |
| ↳ `id` | string | Target ID |
| ↳ `type` | string | Target type |
| ↳ `schedule_id` | string | Schedule ID if type is schedule |
| ↳ `user_id` | string | User ID if type is user |
| ↳ `urgency` | string | Urgency level |
| ↳ `type` | string | Target type |
| ↳ `schedule_id` | string | Schedule ID if type is schedule |
| ↳ `user_id` | string | User ID if type is user |
| ↳ `urgency` | string | Urgency level |
| ↳ `time_to_ack_seconds` | number | Time to acknowledge in seconds |
| ↳ `working_hours` | array | Working hours configuration | | ↳ `working_hours` | array | Working hours configuration |
| ↳ `weekday` | string | Day of week | | ↳ `weekday` | string | Day of week |
| ↳ `start_time` | string | Start time | | ↳ `start_time` | string | Start time |
| ↳ `end_time` | string | End time | | ↳ `end_time` | string | End time |
| ↳ `weekday` | string | Day of week |
| ↳ `start_time` | string | Start time |
| ↳ `end_time` | string | End time |
| ↳ `created_at` | string | When the path was created | | ↳ `created_at` | string | When the path was created |
| ↳ `updated_at` | string | When the path was last updated | | ↳ `updated_at` | string | When the path was last updated |
@@ -1258,7 +1201,7 @@ Get details of a specific escalation path in incident.io
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `escalation_path` | object | The escalation path details | | `escalation_path` | object | The escalation path details |
| ↳ `id` | string | Target ID | | ↳ `id` | string | The escalation path ID |
| ↳ `name` | string | The escalation path name | | ↳ `name` | string | The escalation path name |
| ↳ `path` | array | Array of escalation levels | | ↳ `path` | array | Array of escalation levels |
| ↳ `targets` | array | Targets for this level | | ↳ `targets` | array | Targets for this level |
@@ -1267,30 +1210,11 @@ Get details of a specific escalation path in incident.io
| ↳ `schedule_id` | string | Schedule ID if type is schedule | | ↳ `schedule_id` | string | Schedule ID if type is schedule |
| ↳ `user_id` | string | User ID if type is user | | ↳ `user_id` | string | User ID if type is user |
| ↳ `urgency` | string | Urgency level | | ↳ `urgency` | string | Urgency level |
| ↳ `id` | string | Target ID |
| ↳ `type` | string | Target type |
| ↳ `schedule_id` | string | Schedule ID if type is schedule |
| ↳ `user_id` | string | User ID if type is user |
| ↳ `urgency` | string | Urgency level |
| ↳ `time_to_ack_seconds` | number | Time to acknowledge in seconds | | ↳ `time_to_ack_seconds` | number | Time to acknowledge in seconds |
| ↳ `targets` | array | Targets for this level |
| ↳ `id` | string | Target ID |
| ↳ `type` | string | Target type |
| ↳ `schedule_id` | string | Schedule ID if type is schedule |
| ↳ `user_id` | string | User ID if type is user |
| ↳ `urgency` | string | Urgency level |
| ↳ `type` | string | Target type |
| ↳ `schedule_id` | string | Schedule ID if type is schedule |
| ↳ `user_id` | string | User ID if type is user |
| ↳ `urgency` | string | Urgency level |
| ↳ `time_to_ack_seconds` | number | Time to acknowledge in seconds |
| ↳ `working_hours` | array | Working hours configuration | | ↳ `working_hours` | array | Working hours configuration |
| ↳ `weekday` | string | Day of week | | ↳ `weekday` | string | Day of week |
| ↳ `start_time` | string | Start time | | ↳ `start_time` | string | Start time |
| ↳ `end_time` | string | End time | | ↳ `end_time` | string | End time |
| ↳ `weekday` | string | Day of week |
| ↳ `start_time` | string | Start time |
| ↳ `end_time` | string | End time |
| ↳ `created_at` | string | When the path was created | | ↳ `created_at` | string | When the path was created |
| ↳ `updated_at` | string | When the path was last updated | | ↳ `updated_at` | string | When the path was last updated |
@@ -1313,7 +1237,7 @@ Update an existing escalation path in incident.io
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `escalation_path` | object | The updated escalation path | | `escalation_path` | object | The updated escalation path |
| ↳ `id` | string | Target ID | | ↳ `id` | string | The escalation path ID |
| ↳ `name` | string | The escalation path name | | ↳ `name` | string | The escalation path name |
| ↳ `path` | array | Array of escalation levels | | ↳ `path` | array | Array of escalation levels |
| ↳ `targets` | array | Targets for this level | | ↳ `targets` | array | Targets for this level |
@@ -1322,30 +1246,11 @@ Update an existing escalation path in incident.io
| ↳ `schedule_id` | string | Schedule ID if type is schedule | | ↳ `schedule_id` | string | Schedule ID if type is schedule |
| ↳ `user_id` | string | User ID if type is user | | ↳ `user_id` | string | User ID if type is user |
| ↳ `urgency` | string | Urgency level | | ↳ `urgency` | string | Urgency level |
| ↳ `id` | string | Target ID |
| ↳ `type` | string | Target type |
| ↳ `schedule_id` | string | Schedule ID if type is schedule |
| ↳ `user_id` | string | User ID if type is user |
| ↳ `urgency` | string | Urgency level |
| ↳ `time_to_ack_seconds` | number | Time to acknowledge in seconds | | ↳ `time_to_ack_seconds` | number | Time to acknowledge in seconds |
| ↳ `targets` | array | Targets for this level |
| ↳ `id` | string | Target ID |
| ↳ `type` | string | Target type |
| ↳ `schedule_id` | string | Schedule ID if type is schedule |
| ↳ `user_id` | string | User ID if type is user |
| ↳ `urgency` | string | Urgency level |
| ↳ `type` | string | Target type |
| ↳ `schedule_id` | string | Schedule ID if type is schedule |
| ↳ `user_id` | string | User ID if type is user |
| ↳ `urgency` | string | Urgency level |
| ↳ `time_to_ack_seconds` | number | Time to acknowledge in seconds |
| ↳ `working_hours` | array | Working hours configuration | | ↳ `working_hours` | array | Working hours configuration |
| ↳ `weekday` | string | Day of week | | ↳ `weekday` | string | Day of week |
| ↳ `start_time` | string | Start time | | ↳ `start_time` | string | Start time |
| ↳ `end_time` | string | End time | | ↳ `end_time` | string | End time |
| ↳ `weekday` | string | Day of week |
| ↳ `start_time` | string | Start time |
| ↳ `end_time` | string | End time |
| ↳ `created_at` | string | When the path was created | | ↳ `created_at` | string | When the path was created |
| ↳ `updated_at` | string | When the path was last updated | | ↳ `updated_at` | string | When the path was last updated |

View File

@@ -62,7 +62,7 @@ Create a new contact in Intercom with email, external_id, or role. Returns API-a
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `contact` | object | Created contact object | | `contact` | object | Created contact object |
| ↳ `id` | string | Unique identifier for the contact | | ↳ `id` | string | Unique identifier for the contact |
| ↳ `type` | string | List type | | ↳ `type` | string | Object type \(contact\) |
| ↳ `role` | string | Role of the contact \(user or lead\) | | ↳ `role` | string | Role of the contact \(user or lead\) |
| ↳ `email` | string | Email address of the contact | | ↳ `email` | string | Email address of the contact |
| ↳ `phone` | string | Phone number of the contact | | ↳ `phone` | string | Phone number of the contact |
@@ -82,10 +82,6 @@ Create a new contact in Intercom with email, external_id, or role. Returns API-a
| ↳ `data` | array | Array of tag objects | | ↳ `data` | array | Array of tag objects |
| ↳ `has_more` | boolean | Whether there are more tags | | ↳ `has_more` | boolean | Whether there are more tags |
| ↳ `total_count` | number | Total number of tags | | ↳ `total_count` | number | Total number of tags |
| ↳ `url` | string | URL to fetch companies |
| ↳ `data` | array | Array of social profile objects |
| ↳ `has_more` | boolean | Whether there are more companies |
| ↳ `total_count` | number | Total number of companies |
| ↳ `notes` | object | Notes associated with the contact | | ↳ `notes` | object | Notes associated with the contact |
| ↳ `type` | string | List type | | ↳ `type` | string | List type |
| ↳ `url` | string | URL to fetch notes | | ↳ `url` | string | URL to fetch notes |
@@ -105,11 +101,6 @@ Create a new contact in Intercom with email, external_id, or role. Returns API-a
| ↳ `country` | string | Country | | ↳ `country` | string | Country |
| ↳ `country_code` | string | Country code | | ↳ `country_code` | string | Country code |
| ↳ `continent_code` | string | Continent code | | ↳ `continent_code` | string | Continent code |
| ↳ `city` | string | City |
| ↳ `region` | string | Region/State |
| ↳ `country` | string | Country |
| ↳ `country_code` | string | Country code |
| ↳ `continent_code` | string | Continent code |
| ↳ `social_profiles` | object | Social profiles of the contact | | ↳ `social_profiles` | object | Social profiles of the contact |
| ↳ `type` | string | List type | | ↳ `type` | string | List type |
| ↳ `data` | array | Array of social profile objects | | ↳ `data` | array | Array of social profile objects |
@@ -323,7 +314,7 @@ Create or update a company in Intercom
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `company` | object | Created or updated company object | | `company` | object | Created or updated company object |
| ↳ `id` | string | Unique identifier for the company | | ↳ `id` | string | Unique identifier for the company |
| ↳ `type` | string | Segment list type | | ↳ `type` | string | Object type \(company\) |
| ↳ `app_id` | string | Intercom app ID | | ↳ `app_id` | string | Intercom app ID |
| ↳ `company_id` | string | Your unique identifier for the company | | ↳ `company_id` | string | Your unique identifier for the company |
| ↳ `name` | string | Name of the company | | ↳ `name` | string | Name of the company |
@@ -338,8 +329,12 @@ Create or update a company in Intercom
| ↳ `updated_at` | number | Unix timestamp when company was last updated | | ↳ `updated_at` | number | Unix timestamp when company was last updated |
| ↳ `remote_created_at` | number | Unix timestamp when company was created by you | | ↳ `remote_created_at` | number | Unix timestamp when company was created by you |
| ↳ `custom_attributes` | object | Custom attributes set on the company | | ↳ `custom_attributes` | object | Custom attributes set on the company |
| ↳ `tags` | array | Array of tag objects | | ↳ `tags` | object | Tags associated with the company |
| ↳ `segments` | array | Array of segment objects | | ↳ `type` | string | Tag list type |
| ↳ `tags` | array | Array of tag objects |
| ↳ `segments` | object | Segments the company belongs to |
| ↳ `type` | string | Segment list type |
| ↳ `segments` | array | Array of segment objects |
| `companyId` | string | ID of the created/updated company | | `companyId` | string | ID of the created/updated company |
### `intercom_get_company` ### `intercom_get_company`

View File

@@ -12,6 +12,7 @@
"calendly", "calendly",
"circleback", "circleback",
"clay", "clay",
"clerk",
"confluence", "confluence",
"cursor", "cursor",
"datadog", "datadog",

View File

@@ -64,19 +64,10 @@ Parse PDF documents using Mistral OCR API
| ↳ `bottom_right_x` | number | Bottom-right X coordinate in pixels | | ↳ `bottom_right_x` | number | Bottom-right X coordinate in pixels |
| ↳ `bottom_right_y` | number | Bottom-right Y coordinate in pixels | | ↳ `bottom_right_y` | number | Bottom-right Y coordinate in pixels |
| ↳ `image_base64` | string | Base64-encoded image data \(when include_image_base64=true\) | | ↳ `image_base64` | string | Base64-encoded image data \(when include_image_base64=true\) |
| ↳ `id` | string | Image identifier \(e.g., img-0.jpeg\) |
| ↳ `top_left_x` | number | Top-left X coordinate in pixels |
| ↳ `top_left_y` | number | Top-left Y coordinate in pixels |
| ↳ `bottom_right_x` | number | Bottom-right X coordinate in pixels |
| ↳ `bottom_right_y` | number | Bottom-right Y coordinate in pixels |
| ↳ `image_base64` | string | Base64-encoded image data \(when include_image_base64=true\) |
| ↳ `dimensions` | object | Page dimensions | | ↳ `dimensions` | object | Page dimensions |
| ↳ `dpi` | number | Dots per inch | | ↳ `dpi` | number | Dots per inch |
| ↳ `height` | number | Page height in pixels | | ↳ `height` | number | Page height in pixels |
| ↳ `width` | number | Page width in pixels | | ↳ `width` | number | Page width in pixels |
| ↳ `dpi` | number | Dots per inch |
| ↳ `height` | number | Page height in pixels |
| ↳ `width` | number | Page width in pixels |
| ↳ `tables` | array | Extracted tables as HTML/markdown \(when table_format is set\). Referenced via placeholders like \[tbl-0.html\] | | ↳ `tables` | array | Extracted tables as HTML/markdown \(when table_format is set\). Referenced via placeholders like \[tbl-0.html\] |
| ↳ `hyperlinks` | array | Array of URL strings detected in the page \(e.g., \[ | | ↳ `hyperlinks` | array | Array of URL strings detected in the page \(e.g., \[ |
| ↳ `header` | string | Page header content \(when extract_header=true\) | | ↳ `header` | string | Page header content \(when extract_header=true\) |

View File

@@ -59,7 +59,5 @@ Generate embeddings from text using OpenAI
| ↳ `usage` | object | Token usage information | | ↳ `usage` | object | Token usage information |
| ↳ `prompt_tokens` | number | Number of tokens in the prompt | | ↳ `prompt_tokens` | number | Number of tokens in the prompt |
| ↳ `total_tokens` | number | Total number of tokens used | | ↳ `total_tokens` | number | Total number of tokens used |
| ↳ `prompt_tokens` | number | Number of tokens in the prompt |
| ↳ `total_tokens` | number | Total number of tokens used |

View File

@@ -112,9 +112,6 @@ Conduct comprehensive deep research across the web using Parallel AI. Synthesize
| ↳ `url` | string | Source URL | | ↳ `url` | string | Source URL |
| ↳ `title` | string | Source title | | ↳ `title` | string | Source title |
| ↳ `excerpts` | array | Relevant excerpts from the source | | ↳ `excerpts` | array | Relevant excerpts from the source |
| ↳ `url` | string | Source URL |
| ↳ `title` | string | Source title |
| ↳ `excerpts` | array | Relevant excerpts from the source |
| ↳ `confidence` | string | Confidence level indicator | | ↳ `confidence` | string | Confidence level indicator |

View File

@@ -323,8 +323,6 @@ Retrieve the order book summary for a specific token
| ↳ `bids` | array | Bid orders | | ↳ `bids` | array | Bid orders |
| ↳ `price` | string | Bid price | | ↳ `price` | string | Bid price |
| ↳ `size` | string | Bid size | | ↳ `size` | string | Bid size |
| ↳ `price` | string | Ask price |
| ↳ `size` | string | Ask size |
| ↳ `asks` | array | Ask orders | | ↳ `asks` | array | Ask orders |
| ↳ `price` | string | Ask price | | ↳ `price` | string | Ask price |
| ↳ `size` | string | Ask size | | ↳ `size` | string | Ask size |
@@ -637,15 +635,5 @@ Retrieve top holders of a specific market token
| ↳ `name` | string | Holder display name | | ↳ `name` | string | Holder display name |
| ↳ `profileImage` | string | Profile image URL | | ↳ `profileImage` | string | Profile image URL |
| ↳ `profileImageOptimized` | string | Optimized profile image URL | | ↳ `profileImageOptimized` | string | Optimized profile image URL |
| ↳ `proxyWallet` | string | Holder wallet address |
| ↳ `bio` | string | Holder bio |
| ↳ `asset` | string | Asset ID |
| ↳ `pseudonym` | string | Holder pseudonym |
| ↳ `amount` | number | Amount held |
| ↳ `displayUsernamePublic` | boolean | Whether username is publicly displayed |
| ↳ `outcomeIndex` | number | Outcome index |
| ↳ `name` | string | Holder display name |
| ↳ `profileImage` | string | Profile image URL |
| ↳ `profileImageOptimized` | string | Optimized profile image URL |

View File

@@ -58,14 +58,9 @@ Retrieve accounts from Salesforce CRM
| ↳ `nextRecordsUrl` | string | URL for next page of results | | ↳ `nextRecordsUrl` | string | URL for next page of results |
| ↳ `totalSize` | number | Total number of records | | ↳ `totalSize` | number | Total number of records |
| ↳ `done` | boolean | Whether all records returned | | ↳ `done` | boolean | Whether all records returned |
| ↳ `nextRecordsUrl` | string | URL for next page of results |
| ↳ `totalSize` | number | Total number of records |
| ↳ `done` | boolean | Whether all records returned |
| ↳ `metadata` | object | Response metadata | | ↳ `metadata` | object | Response metadata |
| ↳ `totalReturned` | number | Number of accounts returned | | ↳ `totalReturned` | number | Number of accounts returned |
| ↳ `hasMore` | boolean | Whether more records exist | | ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `totalReturned` | number | Number of accounts returned |
| ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `success` | boolean | Salesforce operation success | | ↳ `success` | boolean | Salesforce operation success |
### `salesforce_create_account` ### `salesforce_create_account`
@@ -184,14 +179,9 @@ Get contact(s) from Salesforce - single contact if ID provided, or list if not
| ↳ `nextRecordsUrl` | string | URL for next page of results | | ↳ `nextRecordsUrl` | string | URL for next page of results |
| ↳ `totalSize` | number | Total number of records | | ↳ `totalSize` | number | Total number of records |
| ↳ `done` | boolean | Whether all records returned | | ↳ `done` | boolean | Whether all records returned |
| ↳ `nextRecordsUrl` | string | URL for next page of results |
| ↳ `totalSize` | number | Total number of records |
| ↳ `done` | boolean | Whether all records returned |
| ↳ `metadata` | object | Response metadata | | ↳ `metadata` | object | Response metadata |
| ↳ `totalReturned` | number | Number of contacts returned | | ↳ `totalReturned` | number | Number of contacts returned |
| ↳ `hasMore` | boolean | Whether more records exist | | ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `totalReturned` | number | Number of contacts returned |
| ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `singleContact` | boolean | Whether single contact was returned | | ↳ `singleContact` | boolean | Whether single contact was returned |
| ↳ `success` | boolean | Salesforce operation success | | ↳ `success` | boolean | Salesforce operation success |
@@ -311,14 +301,9 @@ Get lead(s) from Salesforce
| ↳ `nextRecordsUrl` | string | URL for next page of results | | ↳ `nextRecordsUrl` | string | URL for next page of results |
| ↳ `totalSize` | number | Total number of records | | ↳ `totalSize` | number | Total number of records |
| ↳ `done` | boolean | Whether all records returned | | ↳ `done` | boolean | Whether all records returned |
| ↳ `nextRecordsUrl` | string | URL for next page of results |
| ↳ `totalSize` | number | Total number of records |
| ↳ `done` | boolean | Whether all records returned |
| ↳ `metadata` | object | Response metadata | | ↳ `metadata` | object | Response metadata |
| ↳ `totalReturned` | number | Number of leads returned | | ↳ `totalReturned` | number | Number of leads returned |
| ↳ `hasMore` | boolean | Whether more records exist | | ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `totalReturned` | number | Number of leads returned |
| ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `singleLead` | boolean | Whether single lead was returned | | ↳ `singleLead` | boolean | Whether single lead was returned |
| ↳ `success` | boolean | Operation success status | | ↳ `success` | boolean | Operation success status |
@@ -430,14 +415,9 @@ Get opportunity(ies) from Salesforce
| ↳ `nextRecordsUrl` | string | URL for next page of results | | ↳ `nextRecordsUrl` | string | URL for next page of results |
| ↳ `totalSize` | number | Total number of records | | ↳ `totalSize` | number | Total number of records |
| ↳ `done` | boolean | Whether all records returned | | ↳ `done` | boolean | Whether all records returned |
| ↳ `nextRecordsUrl` | string | URL for next page of results |
| ↳ `totalSize` | number | Total number of records |
| ↳ `done` | boolean | Whether all records returned |
| ↳ `metadata` | object | Response metadata | | ↳ `metadata` | object | Response metadata |
| ↳ `totalReturned` | number | Number of opportunities returned | | ↳ `totalReturned` | number | Number of opportunities returned |
| ↳ `hasMore` | boolean | Whether more records exist | | ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `totalReturned` | number | Number of opportunities returned |
| ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `success` | boolean | Operation success status | | ↳ `success` | boolean | Operation success status |
### `salesforce_create_opportunity` ### `salesforce_create_opportunity`
@@ -544,14 +524,9 @@ Get case(s) from Salesforce
| ↳ `nextRecordsUrl` | string | URL for next page of results | | ↳ `nextRecordsUrl` | string | URL for next page of results |
| ↳ `totalSize` | number | Total number of records | | ↳ `totalSize` | number | Total number of records |
| ↳ `done` | boolean | Whether all records returned | | ↳ `done` | boolean | Whether all records returned |
| ↳ `nextRecordsUrl` | string | URL for next page of results |
| ↳ `totalSize` | number | Total number of records |
| ↳ `done` | boolean | Whether all records returned |
| ↳ `metadata` | object | Response metadata | | ↳ `metadata` | object | Response metadata |
| ↳ `totalReturned` | number | Number of cases returned | | ↳ `totalReturned` | number | Number of cases returned |
| ↳ `hasMore` | boolean | Whether more records exist | | ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `totalReturned` | number | Number of cases returned |
| ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `success` | boolean | Operation success status | | ↳ `success` | boolean | Operation success status |
### `salesforce_create_case` ### `salesforce_create_case`
@@ -655,14 +630,9 @@ Get task(s) from Salesforce
| ↳ `nextRecordsUrl` | string | URL for next page of results | | ↳ `nextRecordsUrl` | string | URL for next page of results |
| ↳ `totalSize` | number | Total number of records | | ↳ `totalSize` | number | Total number of records |
| ↳ `done` | boolean | Whether all records returned | | ↳ `done` | boolean | Whether all records returned |
| ↳ `nextRecordsUrl` | string | URL for next page of results |
| ↳ `totalSize` | number | Total number of records |
| ↳ `done` | boolean | Whether all records returned |
| ↳ `metadata` | object | Response metadata | | ↳ `metadata` | object | Response metadata |
| ↳ `totalReturned` | number | Number of tasks returned | | ↳ `totalReturned` | number | Number of tasks returned |
| ↳ `hasMore` | boolean | Whether more records exist | | ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `totalReturned` | number | Number of tasks returned |
| ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `success` | boolean | Operation success status | | ↳ `success` | boolean | Operation success status |
### `salesforce_create_task` ### `salesforce_create_task`
@@ -938,8 +908,6 @@ Execute a custom SOQL query to retrieve data from Salesforce
| ↳ `metadata` | object | Response metadata | | ↳ `metadata` | object | Response metadata |
| ↳ `totalReturned` | number | Number of records returned in this response | | ↳ `totalReturned` | number | Number of records returned in this response |
| ↳ `hasMore` | boolean | Whether more records exist | | ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `totalReturned` | number | Number of records returned in this response |
| ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `success` | boolean | Salesforce operation success | | ↳ `success` | boolean | Salesforce operation success |
### `salesforce_query_more` ### `salesforce_query_more`
@@ -967,8 +935,6 @@ Retrieve additional query results using the nextRecordsUrl from a previous query
| ↳ `metadata` | object | Response metadata | | ↳ `metadata` | object | Response metadata |
| ↳ `totalReturned` | number | Number of records returned in this response | | ↳ `totalReturned` | number | Number of records returned in this response |
| ↳ `hasMore` | boolean | Whether more records exist | | ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `totalReturned` | number | Number of records returned in this response |
| ↳ `hasMore` | boolean | Whether more records exist |
| ↳ `success` | boolean | Salesforce operation success | | ↳ `success` | boolean | Salesforce operation success |
### `salesforce_describe_object` ### `salesforce_describe_object`

View File

@@ -68,7 +68,7 @@ List issues from Sentry for a specific organization and optionally a specific pr
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `issues` | array | List of Sentry issues | | `issues` | array | List of Sentry issues |
| ↳ `id` | string | User ID | | ↳ `id` | string | Unique issue ID |
| ↳ `shortId` | string | Short issue identifier | | ↳ `shortId` | string | Short issue identifier |
| ↳ `title` | string | Issue title | | ↳ `title` | string | Issue title |
| ↳ `culprit` | string | Function or location that caused the issue | | ↳ `culprit` | string | Function or location that caused the issue |
@@ -78,27 +78,22 @@ List issues from Sentry for a specific organization and optionally a specific pr
| ↳ `status` | string | Current issue status | | ↳ `status` | string | Current issue status |
| ↳ `statusDetails` | object | Additional details about the status | | ↳ `statusDetails` | object | Additional details about the status |
| ↳ `isPublic` | boolean | Whether the issue is publicly visible | | ↳ `isPublic` | boolean | Whether the issue is publicly visible |
| ↳ `platform` | string | Project platform | | ↳ `platform` | string | Platform where the issue occurred |
| ↳ `project` | object | Project information | | ↳ `project` | object | Project information |
| ↳ `id` | string | Project ID | | ↳ `id` | string | Project ID |
| ↳ `name` | string | Project name | | ↳ `name` | string | Project name |
| ↳ `slug` | string | Project slug | | ↳ `slug` | string | Project slug |
| ↳ `platform` | string | Project platform | | ↳ `platform` | string | Project platform |
| ↳ `name` | string | User name | | ↳ `type` | string | Issue type |
| ↳ `slug` | string | Project slug |
| ↳ `type` | string | Type of error \(e.g., TypeError\) |
| ↳ `metadata` | object | Error metadata | | ↳ `metadata` | object | Error metadata |
| ↳ `type` | string | Type of error \(e.g., TypeError\) | | ↳ `type` | string | Type of error \(e.g., TypeError\) |
| ↳ `value` | string | Error message or value | | ↳ `value` | string | Error message or value |
| ↳ `function` | string | Function where the error occurred | | ↳ `function` | string | Function where the error occurred |
| ↳ `value` | string | Error message or value |
| ↳ `function` | string | Function where the error occurred |
| ↳ `numComments` | number | Number of comments on the issue | | ↳ `numComments` | number | Number of comments on the issue |
| ↳ `assignedTo` | object | User assigned to the issue | | ↳ `assignedTo` | object | User assigned to the issue |
| ↳ `id` | string | User ID | | ↳ `id` | string | User ID |
| ↳ `name` | string | User name | | ↳ `name` | string | User name |
| ↳ `email` | string | User email | | ↳ `email` | string | User email |
| ↳ `email` | string | User email |
| ↳ `isBookmarked` | boolean | Whether the issue is bookmarked | | ↳ `isBookmarked` | boolean | Whether the issue is bookmarked |
| ↳ `isSubscribed` | boolean | Whether subscribed to updates | | ↳ `isSubscribed` | boolean | Whether subscribed to updates |
| ↳ `hasSeen` | boolean | Whether the user has seen this issue | | ↳ `hasSeen` | boolean | Whether the user has seen this issue |
@@ -130,7 +125,7 @@ Retrieve detailed information about a specific Sentry issue by its ID. Returns c
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `issue` | object | Detailed information about the Sentry issue | | `issue` | object | Detailed information about the Sentry issue |
| ↳ `id` | string | User ID | | ↳ `id` | string | Unique issue ID |
| ↳ `shortId` | string | Short issue identifier | | ↳ `shortId` | string | Short issue identifier |
| ↳ `title` | string | Issue title | | ↳ `title` | string | Issue title |
| ↳ `culprit` | string | Function or location that caused the issue | | ↳ `culprit` | string | Function or location that caused the issue |
@@ -140,27 +135,22 @@ Retrieve detailed information about a specific Sentry issue by its ID. Returns c
| ↳ `status` | string | Current issue status | | ↳ `status` | string | Current issue status |
| ↳ `statusDetails` | object | Additional details about the status | | ↳ `statusDetails` | object | Additional details about the status |
| ↳ `isPublic` | boolean | Whether the issue is publicly visible | | ↳ `isPublic` | boolean | Whether the issue is publicly visible |
| ↳ `platform` | string | Project platform | | ↳ `platform` | string | Platform where the issue occurred |
| ↳ `project` | object | Project information | | ↳ `project` | object | Project information |
| ↳ `id` | string | Project ID | | ↳ `id` | string | Project ID |
| ↳ `name` | string | Project name | | ↳ `name` | string | Project name |
| ↳ `slug` | string | Project slug | | ↳ `slug` | string | Project slug |
| ↳ `platform` | string | Project platform | | ↳ `platform` | string | Project platform |
| ↳ `name` | string | User name | | ↳ `type` | string | Issue type |
| ↳ `slug` | string | Project slug |
| ↳ `type` | string | Type of error \(e.g., TypeError, ValueError\) |
| ↳ `metadata` | object | Error metadata | | ↳ `metadata` | object | Error metadata |
| ↳ `type` | string | Type of error \(e.g., TypeError, ValueError\) | | ↳ `type` | string | Type of error \(e.g., TypeError, ValueError\) |
| ↳ `value` | string | Error message or value | | ↳ `value` | string | Error message or value |
| ↳ `function` | string | Function where the error occurred | | ↳ `function` | string | Function where the error occurred |
| ↳ `value` | string | Error message or value |
| ↳ `function` | string | Function where the error occurred |
| ↳ `numComments` | number | Number of comments on the issue | | ↳ `numComments` | number | Number of comments on the issue |
| ↳ `assignedTo` | object | User assigned to the issue \(if any\) | | ↳ `assignedTo` | object | User assigned to the issue \(if any\) |
| ↳ `id` | string | User ID | | ↳ `id` | string | User ID |
| ↳ `name` | string | User name | | ↳ `name` | string | User name |
| ↳ `email` | string | User email | | ↳ `email` | string | User email |
| ↳ `email` | string | User email |
| ↳ `isBookmarked` | boolean | Whether the issue is bookmarked | | ↳ `isBookmarked` | boolean | Whether the issue is bookmarked |
| ↳ `isSubscribed` | boolean | Whether the user is subscribed to updates | | ↳ `isSubscribed` | boolean | Whether the user is subscribed to updates |
| ↳ `hasSeen` | boolean | Whether the user has seen this issue | | ↳ `hasSeen` | boolean | Whether the user has seen this issue |
@@ -194,7 +184,7 @@ Update a Sentry issue by changing its status, assignment, bookmark state, or oth
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `issue` | object | The updated Sentry issue | | `issue` | object | The updated Sentry issue |
| ↳ `id` | string | User ID | | ↳ `id` | string | Unique issue ID |
| ↳ `shortId` | string | Short issue identifier | | ↳ `shortId` | string | Short issue identifier |
| ↳ `title` | string | Issue title | | ↳ `title` | string | Issue title |
| ↳ `status` | string | Updated issue status | | ↳ `status` | string | Updated issue status |
@@ -202,8 +192,6 @@ Update a Sentry issue by changing its status, assignment, bookmark state, or oth
| ↳ `id` | string | User ID | | ↳ `id` | string | User ID |
| ↳ `name` | string | User name | | ↳ `name` | string | User name |
| ↳ `email` | string | User email | | ↳ `email` | string | User email |
| ↳ `name` | string | User name |
| ↳ `email` | string | User email |
| ↳ `isBookmarked` | boolean | Whether the issue is bookmarked | | ↳ `isBookmarked` | boolean | Whether the issue is bookmarked |
| ↳ `isSubscribed` | boolean | Whether the user is subscribed to updates | | ↳ `isSubscribed` | boolean | Whether the user is subscribed to updates |
| ↳ `isPublic` | boolean | Whether the issue is publicly visible | | ↳ `isPublic` | boolean | Whether the issue is publicly visible |
@@ -227,9 +215,9 @@ List all projects in a Sentry organization. Returns project details including na
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `projects` | array | List of Sentry projects | | `projects` | array | List of Sentry projects |
| ↳ `id` | string | Team ID | | ↳ `id` | string | Unique project ID |
| ↳ `slug` | string | Team slug | | ↳ `slug` | string | URL-friendly project identifier |
| ↳ `name` | string | Team name | | ↳ `name` | string | Project name |
| ↳ `platform` | string | Platform/language \(e.g., javascript, python\) | | ↳ `platform` | string | Platform/language \(e.g., javascript, python\) |
| ↳ `dateCreated` | string | When the project was created \(ISO timestamp\) | | ↳ `dateCreated` | string | When the project was created \(ISO timestamp\) |
| ↳ `isBookmarked` | boolean | Whether the project is bookmarked | | ↳ `isBookmarked` | boolean | Whether the project is bookmarked |
@@ -266,9 +254,9 @@ Retrieve detailed information about a specific Sentry project by its slug. Retur
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `project` | object | Detailed information about the Sentry project | | `project` | object | Detailed information about the Sentry project |
| ↳ `id` | string | Team ID | | ↳ `id` | string | Unique project ID |
| ↳ `slug` | string | Team slug | | ↳ `slug` | string | URL-friendly project identifier |
| ↳ `name` | string | Team name | | ↳ `name` | string | Project name |
| ↳ `platform` | string | Platform/language \(e.g., javascript, python\) | | ↳ `platform` | string | Platform/language \(e.g., javascript, python\) |
| ↳ `dateCreated` | string | When the project was created \(ISO timestamp\) | | ↳ `dateCreated` | string | When the project was created \(ISO timestamp\) |
| ↳ `isBookmarked` | boolean | Whether the project is bookmarked | | ↳ `isBookmarked` | boolean | Whether the project is bookmarked |
@@ -321,9 +309,9 @@ Create a new Sentry project in an organization. Requires a team to associate the
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `project` | object | The newly created Sentry project | | `project` | object | The newly created Sentry project |
| ↳ `id` | string | Team ID | | ↳ `id` | string | Unique project ID |
| ↳ `slug` | string | Team slug | | ↳ `slug` | string | URL-friendly project identifier |
| ↳ `name` | string | Team name | | ↳ `name` | string | Project name |
| ↳ `platform` | string | Platform/language | | ↳ `platform` | string | Platform/language |
| ↳ `dateCreated` | string | When the project was created \(ISO timestamp\) | | ↳ `dateCreated` | string | When the project was created \(ISO timestamp\) |
| ↳ `isBookmarked` | boolean | Whether the project is bookmarked | | ↳ `isBookmarked` | boolean | Whether the project is bookmarked |
@@ -370,9 +358,9 @@ Update a Sentry project by changing its name, slug, platform, or other settings.
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `project` | object | The updated Sentry project | | `project` | object | The updated Sentry project |
| ↳ `id` | string | Team ID | | ↳ `id` | string | Unique project ID |
| ↳ `slug` | string | Team slug | | ↳ `slug` | string | URL-friendly project identifier |
| ↳ `name` | string | Team name | | ↳ `name` | string | Project name |
| ↳ `platform` | string | Platform/language | | ↳ `platform` | string | Platform/language |
| ↳ `isBookmarked` | boolean | Whether the project is bookmarked | | ↳ `isBookmarked` | boolean | Whether the project is bookmarked |
| ↳ `organization` | object | Organization information | | ↳ `organization` | object | Organization information |
@@ -406,7 +394,7 @@ List events from a Sentry project. Can be filtered by issue ID, query, or time p
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `events` | array | List of Sentry events | | `events` | array | List of Sentry events |
| ↳ `id` | string | User ID | | ↳ `id` | string | Unique event ID |
| ↳ `eventID` | string | Event identifier | | ↳ `eventID` | string | Event identifier |
| ↳ `projectID` | string | Project ID | | ↳ `projectID` | string | Project ID |
| ↳ `groupID` | string | Issue group ID | | ↳ `groupID` | string | Issue group ID |
@@ -422,23 +410,16 @@ List events from a Sentry project. Can be filtered by issue ID, query, or time p
| ↳ `username` | string | Username | | ↳ `username` | string | Username |
| ↳ `ipAddress` | string | IP address | | ↳ `ipAddress` | string | IP address |
| ↳ `name` | string | User display name | | ↳ `name` | string | User display name |
| ↳ `email` | string | User email |
| ↳ `username` | string | Username |
| ↳ `ipAddress` | string | IP address |
| ↳ `name` | string | SDK name |
| ↳ `tags` | array | Tags associated with the event | | ↳ `tags` | array | Tags associated with the event |
| ↳ `key` | string | Tag key | | ↳ `key` | string | Tag key |
| ↳ `value` | string | Tag value | | ↳ `value` | string | Tag value |
| ↳ `key` | string | Tag key |
| ↳ `value` | string | Error message or value |
| ↳ `contexts` | object | Additional context data \(device, OS, etc.\) | | ↳ `contexts` | object | Additional context data \(device, OS, etc.\) |
| ↳ `platform` | string | Platform where the event occurred | | ↳ `platform` | string | Platform where the event occurred |
| ↳ `type` | string | Type of error \(e.g., TypeError\) | | ↳ `type` | string | Event type |
| ↳ `metadata` | object | Error metadata | | ↳ `metadata` | object | Error metadata |
| ↳ `type` | string | Type of error \(e.g., TypeError\) | | ↳ `type` | string | Type of error \(e.g., TypeError\) |
| ↳ `value` | string | Error message or value | | ↳ `value` | string | Error message or value |
| ↳ `function` | string | Function where the error occurred | | ↳ `function` | string | Function where the error occurred |
| ↳ `function` | string | Function where the error occurred |
| ↳ `entries` | array | Event entries \(exception, breadcrumbs, etc.\) | | ↳ `entries` | array | Event entries \(exception, breadcrumbs, etc.\) |
| ↳ `errors` | array | Processing errors | | ↳ `errors` | array | Processing errors |
| ↳ `dist` | string | Distribution identifier | | ↳ `dist` | string | Distribution identifier |
@@ -446,7 +427,6 @@ List events from a Sentry project. Can be filtered by issue ID, query, or time p
| ↳ `sdk` | object | SDK information | | ↳ `sdk` | object | SDK information |
| ↳ `name` | string | SDK name | | ↳ `name` | string | SDK name |
| ↳ `version` | string | SDK version | | ↳ `version` | string | SDK version |
| ↳ `version` | string | SDK version |
| `metadata` | object | Pagination metadata | | `metadata` | object | Pagination metadata |
| ↳ `nextCursor` | string | Cursor for the next page of results \(if available\) | | ↳ `nextCursor` | string | Cursor for the next page of results \(if available\) |
| ↳ `hasMore` | boolean | Whether there are more results available | | ↳ `hasMore` | boolean | Whether there are more results available |
@@ -469,7 +449,7 @@ Retrieve detailed information about a specific Sentry event by its ID. Returns c
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `event` | object | Detailed information about the Sentry event | | `event` | object | Detailed information about the Sentry event |
| ↳ `id` | string | User ID | | ↳ `id` | string | Unique event ID |
| ↳ `eventID` | string | Event identifier | | ↳ `eventID` | string | Event identifier |
| ↳ `projectID` | string | Project ID | | ↳ `projectID` | string | Project ID |
| ↳ `groupID` | string | Issue group ID this event belongs to | | ↳ `groupID` | string | Issue group ID this event belongs to |
@@ -485,23 +465,16 @@ Retrieve detailed information about a specific Sentry event by its ID. Returns c
| ↳ `username` | string | Username | | ↳ `username` | string | Username |
| ↳ `ipAddress` | string | IP address | | ↳ `ipAddress` | string | IP address |
| ↳ `name` | string | User display name | | ↳ `name` | string | User display name |
| ↳ `email` | string | User email |
| ↳ `username` | string | Username |
| ↳ `ipAddress` | string | IP address |
| ↳ `name` | string | SDK name |
| ↳ `tags` | array | Tags associated with the event | | ↳ `tags` | array | Tags associated with the event |
| ↳ `key` | string | Tag key | | ↳ `key` | string | Tag key |
| ↳ `value` | string | Tag value | | ↳ `value` | string | Tag value |
| ↳ `key` | string | Tag key |
| ↳ `value` | string | Error message or value |
| ↳ `contexts` | object | Additional context data \(device, OS, browser, etc.\) | | ↳ `contexts` | object | Additional context data \(device, OS, browser, etc.\) |
| ↳ `platform` | string | Platform where the event occurred | | ↳ `platform` | string | Platform where the event occurred |
| ↳ `type` | string | Type of error \(e.g., TypeError, ValueError\) | | ↳ `type` | string | Event type \(error, transaction, etc.\) |
| ↳ `metadata` | object | Error metadata | | ↳ `metadata` | object | Error metadata |
| ↳ `type` | string | Type of error \(e.g., TypeError, ValueError\) | | ↳ `type` | string | Type of error \(e.g., TypeError, ValueError\) |
| ↳ `value` | string | Error message or value | | ↳ `value` | string | Error message or value |
| ↳ `function` | string | Function where the error occurred | | ↳ `function` | string | Function where the error occurred |
| ↳ `function` | string | Function where the error occurred |
| ↳ `entries` | array | Event entries including exception, breadcrumbs, and request data | | ↳ `entries` | array | Event entries including exception, breadcrumbs, and request data |
| ↳ `errors` | array | Processing errors that occurred | | ↳ `errors` | array | Processing errors that occurred |
| ↳ `dist` | string | Distribution identifier | | ↳ `dist` | string | Distribution identifier |
@@ -509,7 +482,6 @@ Retrieve detailed information about a specific Sentry event by its ID. Returns c
| ↳ `sdk` | object | SDK information | | ↳ `sdk` | object | SDK information |
| ↳ `name` | string | SDK name | | ↳ `name` | string | SDK name |
| ↳ `version` | string | SDK version | | ↳ `version` | string | SDK version |
| ↳ `version` | string | SDK version |
### `sentry_releases_list` ### `sentry_releases_list`
@@ -531,36 +503,30 @@ List releases for a Sentry organization or project. Returns release details incl
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `releases` | array | List of Sentry releases | | `releases` | array | List of Sentry releases |
| ↳ `id` | string | Project ID | | ↳ `id` | string | Unique release ID |
| ↳ `version` | object | Version details | | ↳ `version` | string | Release version identifier |
| ↳ `raw` | string | Raw version string |
| ↳ `shortVersion` | string | Shortened version identifier | | ↳ `shortVersion` | string | Shortened version identifier |
| ↳ `ref` | string | Git reference \(commit SHA, tag, or branch\) | | ↳ `ref` | string | Git reference \(commit SHA, tag, or branch\) |
| ↳ `url` | string | URL to the release \(e.g., GitHub release page\) | | ↳ `url` | string | URL to the release \(e.g., GitHub release page\) |
| ↳ `dateReleased` | string | When the release was deployed \(ISO timestamp\) | | ↳ `dateReleased` | string | When the release was deployed \(ISO timestamp\) |
| ↳ `dateCreated` | string | Commit timestamp | | ↳ `dateCreated` | string | When the release was created \(ISO timestamp\) |
| ↳ `dateStarted` | string | Deploy start timestamp | | ↳ `dateStarted` | string | When the release started \(ISO timestamp\) |
| ↳ `newGroups` | number | Number of new issues introduced in this release | | ↳ `newGroups` | number | Number of new issues introduced in this release |
| ↳ `owner` | object | Owner of the release | | ↳ `owner` | object | Owner of the release |
| ↳ `id` | string | User ID | | ↳ `id` | string | User ID |
| ↳ `name` | string | User name | | ↳ `name` | string | User name |
| ↳ `email` | string | User email | | ↳ `email` | string | User email |
| ↳ `name` | string | Project name |
| ↳ `email` | string | Author email |
| ↳ `commitCount` | number | Number of commits in this release | | ↳ `commitCount` | number | Number of commits in this release |
| ↳ `deployCount` | number | Number of deploys for this release | | ↳ `deployCount` | number | Number of deploys for this release |
| ↳ `lastCommit` | object | Last commit in the release | | ↳ `lastCommit` | object | Last commit in the release |
| ↳ `id` | string | Commit SHA | | ↳ `id` | string | Commit SHA |
| ↳ `message` | string | Commit message | | ↳ `message` | string | Commit message |
| ↳ `dateCreated` | string | Commit timestamp | | ↳ `dateCreated` | string | Commit timestamp |
| ↳ `message` | string | Commit message |
| ↳ `lastDeploy` | object | Last deploy of the release | | ↳ `lastDeploy` | object | Last deploy of the release |
| ↳ `id` | string | Deploy ID | | ↳ `id` | string | Deploy ID |
| ↳ `environment` | string | Deploy environment | | ↳ `environment` | string | Deploy environment |
| ↳ `dateStarted` | string | Deploy start timestamp | | ↳ `dateStarted` | string | Deploy start timestamp |
| ↳ `dateFinished` | string | Deploy finish timestamp | | ↳ `dateFinished` | string | Deploy finish timestamp |
| ↳ `environment` | string | Deploy environment |
| ↳ `dateFinished` | string | Deploy finish timestamp |
| ↳ `authors` | array | Authors of commits in the release | | ↳ `authors` | array | Authors of commits in the release |
| ↳ `id` | string | Author ID | | ↳ `id` | string | Author ID |
| ↳ `name` | string | Author name | | ↳ `name` | string | Author name |
@@ -570,18 +536,12 @@ List releases for a Sentry organization or project. Returns release details incl
| ↳ `name` | string | Project name | | ↳ `name` | string | Project name |
| ↳ `slug` | string | Project slug | | ↳ `slug` | string | Project slug |
| ↳ `platform` | string | Project platform | | ↳ `platform` | string | Project platform |
| ↳ `slug` | string | Project slug |
| ↳ `platform` | string | Project platform |
| ↳ `firstEvent` | string | First event timestamp | | ↳ `firstEvent` | string | First event timestamp |
| ↳ `lastEvent` | string | Last event timestamp | | ↳ `lastEvent` | string | Last event timestamp |
| ↳ `versionInfo` | object | Version metadata | | ↳ `versionInfo` | object | Version metadata |
| ↳ `buildHash` | string | Build hash | | ↳ `buildHash` | string | Build hash |
| ↳ `version` | object | Version details | | ↳ `version` | object | Version details |
| ↳ `raw` | string | Raw version string | | ↳ `raw` | string | Raw version string |
| ↳ `raw` | string | Raw version string |
| ↳ `package` | string | Package name |
| ↳ `buildHash` | string | Build hash |
| ↳ `raw` | string | Raw version string |
| ↳ `package` | string | Package name | | ↳ `package` | string | Package name |
| `metadata` | object | Pagination metadata | | `metadata` | object | Pagination metadata |
| ↳ `nextCursor` | string | Cursor for the next page of results \(if available\) | | ↳ `nextCursor` | string | Cursor for the next page of results \(if available\) |
@@ -609,15 +569,14 @@ Create a new release in Sentry. A release is a version of your code deployed to
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `release` | object | The newly created Sentry release | | `release` | object | The newly created Sentry release |
| ↳ `id` | string | Project ID | | ↳ `id` | string | Unique release ID |
| ↳ `version` | object | Version details | | ↳ `version` | string | Release version identifier |
| ↳ `raw` | string | Raw version string |
| ↳ `shortVersion` | string | Shortened version identifier | | ↳ `shortVersion` | string | Shortened version identifier |
| ↳ `ref` | string | Git reference \(commit SHA, tag, or branch\) | | ↳ `ref` | string | Git reference \(commit SHA, tag, or branch\) |
| ↳ `url` | string | URL to the release | | ↳ `url` | string | URL to the release |
| ↳ `dateReleased` | string | When the release was deployed \(ISO timestamp\) | | ↳ `dateReleased` | string | When the release was deployed \(ISO timestamp\) |
| ↳ `dateCreated` | string | Commit timestamp | | ↳ `dateCreated` | string | When the release was created \(ISO timestamp\) |
| ↳ `dateStarted` | string | Deploy start timestamp | | ↳ `dateStarted` | string | When the release started \(ISO timestamp\) |
| ↳ `newGroups` | number | Number of new issues introduced | | ↳ `newGroups` | number | Number of new issues introduced |
| ↳ `commitCount` | number | Number of commits in this release | | ↳ `commitCount` | number | Number of commits in this release |
| ↳ `deployCount` | number | Number of deploys for this release | | ↳ `deployCount` | number | Number of deploys for this release |
@@ -625,20 +584,15 @@ Create a new release in Sentry. A release is a version of your code deployed to
| ↳ `id` | string | Owner ID | | ↳ `id` | string | Owner ID |
| ↳ `name` | string | Owner name | | ↳ `name` | string | Owner name |
| ↳ `email` | string | Owner email | | ↳ `email` | string | Owner email |
| ↳ `name` | string | Project name |
| ↳ `email` | string | Author email |
| ↳ `lastCommit` | object | Last commit in the release | | ↳ `lastCommit` | object | Last commit in the release |
| ↳ `id` | string | Commit SHA | | ↳ `id` | string | Commit SHA |
| ↳ `message` | string | Commit message | | ↳ `message` | string | Commit message |
| ↳ `dateCreated` | string | Commit timestamp | | ↳ `dateCreated` | string | Commit timestamp |
| ↳ `message` | string | Commit message |
| ↳ `lastDeploy` | object | Last deploy of the release | | ↳ `lastDeploy` | object | Last deploy of the release |
| ↳ `id` | string | Deploy ID | | ↳ `id` | string | Deploy ID |
| ↳ `environment` | string | Deploy environment | | ↳ `environment` | string | Deploy environment |
| ↳ `dateStarted` | string | Deploy start timestamp | | ↳ `dateStarted` | string | Deploy start timestamp |
| ↳ `dateFinished` | string | Deploy finish timestamp | | ↳ `dateFinished` | string | Deploy finish timestamp |
| ↳ `environment` | string | Deploy environment |
| ↳ `dateFinished` | string | Deploy finish timestamp |
| ↳ `authors` | array | Authors of commits in the release | | ↳ `authors` | array | Authors of commits in the release |
| ↳ `id` | string | Author ID | | ↳ `id` | string | Author ID |
| ↳ `name` | string | Author name | | ↳ `name` | string | Author name |
@@ -648,19 +602,13 @@ Create a new release in Sentry. A release is a version of your code deployed to
| ↳ `name` | string | Project name | | ↳ `name` | string | Project name |
| ↳ `slug` | string | Project slug | | ↳ `slug` | string | Project slug |
| ↳ `platform` | string | Project platform | | ↳ `platform` | string | Project platform |
| ↳ `slug` | string | Project slug |
| ↳ `platform` | string | Project platform |
| ↳ `firstEvent` | string | First event timestamp | | ↳ `firstEvent` | string | First event timestamp |
| ↳ `lastEvent` | string | Last event timestamp | | ↳ `lastEvent` | string | Last event timestamp |
| ↳ `versionInfo` | object | Version metadata | | ↳ `versionInfo` | object | Version metadata |
| ↳ `buildHash` | string | Build hash | | ↳ `buildHash` | string | Build hash |
| ↳ `version` | object | Version details | | ↳ `version` | object | Version details |
| ↳ `raw` | string | Raw version string | | ↳ `raw` | string | Raw version string |
| ↳ `raw` | string | Raw version string |
| ↳ `package` | string | Package name | | ↳ `package` | string | Package name |
| ↳ `buildHash` | string | Build hash |
| ↳ `raw` | string | Raw version string |
| ↳ `package` | string | Package name |
### `sentry_releases_deploy` ### `sentry_releases_deploy`

View File

@@ -95,13 +95,7 @@ Read a specific page from a SharePoint site
| ↳ `pageLayout` | string | The layout type of the page | | ↳ `pageLayout` | string | The layout type of the page |
| ↳ `createdDateTime` | string | When the page was created | | ↳ `createdDateTime` | string | When the page was created |
| ↳ `lastModifiedDateTime` | string | When the page was last modified | | ↳ `lastModifiedDateTime` | string | When the page was last modified |
| ↳ `id` | string | The unique ID of the page | | ↳ `content` | object | Extracted text content from the page |
| ↳ `name` | string | The name of the page |
| ↳ `title` | string | The title of the page |
| ↳ `webUrl` | string | The URL to access the page |
| ↳ `pageLayout` | string | The layout type of the page |
| ↳ `createdDateTime` | string | When the page was created |
| ↳ `lastModifiedDateTime` | string | When the page was last modified |
| ↳ `content` | string | Extracted text content from the page | | ↳ `content` | string | Extracted text content from the page |
| ↳ `canvasLayout` | object | Raw SharePoint canvas layout structure | | ↳ `canvasLayout` | object | Raw SharePoint canvas layout structure |
| `content` | object | Content of the SharePoint page | | `content` | object | Content of the SharePoint page |
@@ -135,10 +129,8 @@ List details of all SharePoint sites
| ↳ `isPersonalSite` | boolean | Whether this is a personal site | | ↳ `isPersonalSite` | boolean | Whether this is a personal site |
| ↳ `root` | object | Server relative URL | | ↳ `root` | object | Server relative URL |
| ↳ `serverRelativeUrl` | string | Server relative URL | | ↳ `serverRelativeUrl` | string | Server relative URL |
| ↳ `serverRelativeUrl` | string | Server relative URL |
| ↳ `siteCollection` | object | Site collection hostname | | ↳ `siteCollection` | object | Site collection hostname |
| ↳ `hostname` | string | Site collection hostname | | ↳ `hostname` | string | Site collection hostname |
| ↳ `hostname` | string | Site collection hostname |
| `sites` | array | List of all accessible SharePoint sites | | `sites` | array | List of all accessible SharePoint sites |
| ↳ `id` | string | The unique ID of the site | | ↳ `id` | string | The unique ID of the site |
| ↳ `name` | string | The name of the site | | ↳ `name` | string | The name of the site |
@@ -193,7 +185,7 @@ Get metadata (and optionally columns/items) for a SharePoint list
| Parameter | Type | Description | | Parameter | Type | Description |
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `list` | object | Information about the SharePoint list | | `list` | object | Information about the SharePoint list |
| ↳ `id` | string | Item ID | | ↳ `id` | string | The unique ID of the list |
| ↳ `displayName` | string | The display name of the list | | ↳ `displayName` | string | The display name of the list |
| ↳ `name` | string | The internal name of the list | | ↳ `name` | string | The internal name of the list |
| ↳ `webUrl` | string | The web URL of the list | | ↳ `webUrl` | string | The web URL of the list |
@@ -201,7 +193,6 @@ Get metadata (and optionally columns/items) for a SharePoint list
| ↳ `lastModifiedDateTime` | string | When the list was last modified | | ↳ `lastModifiedDateTime` | string | When the list was last modified |
| ↳ `list` | object | List properties \(e.g., template\) | | ↳ `list` | object | List properties \(e.g., template\) |
| ↳ `columns` | array | List column definitions | | ↳ `columns` | array | List column definitions |
| ↳ `fields` | object | Field values for the item |
| `lists` | array | All lists in the site when no listId/title provided | | `lists` | array | All lists in the site when no listId/title provided |
### `sharepoint_update_list` ### `sharepoint_update_list`

View File

@@ -147,9 +147,9 @@ Read the latest messages from Slack channels. Retrieve conversation history with
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `messages` | array | Array of message objects from the channel | | `messages` | array | Array of message objects from the channel |
| ↳ `type` | string | Message type | | ↳ `type` | string | Message type |
| ↳ `ts` | string | Edit timestamp | | ↳ `ts` | string | Message timestamp |
| ↳ `text` | string | Message text content | | ↳ `text` | string | Message text content |
| ↳ `user` | string | User ID who edited | | ↳ `user` | string | User ID who sent the message |
| ↳ `bot_id` | string | Bot ID if sent by a bot | | ↳ `bot_id` | string | Bot ID if sent by a bot |
| ↳ `username` | string | Display username | | ↳ `username` | string | Display username |
| ↳ `channel` | string | Channel ID | | ↳ `channel` | string | Channel ID |
@@ -167,9 +167,6 @@ Read the latest messages from Slack channels. Retrieve conversation history with
| ↳ `name` | string | Emoji name | | ↳ `name` | string | Emoji name |
| ↳ `count` | number | Number of reactions | | ↳ `count` | number | Number of reactions |
| ↳ `users` | array | Array of user IDs who reacted | | ↳ `users` | array | Array of user IDs who reacted |
| ↳ `name` | string | File name |
| ↳ `count` | number | Number of reactions |
| ↳ `users` | array | Array of user IDs who reacted |
| ↳ `is_starred` | boolean | Whether message is starred | | ↳ `is_starred` | boolean | Whether message is starred |
| ↳ `pinned_to` | array | Array of channel IDs where message is pinned | | ↳ `pinned_to` | array | Array of channel IDs where message is pinned |
| ↳ `files` | array | Array of files attached to message | | ↳ `files` | array | Array of files attached to message |
@@ -180,17 +177,12 @@ Read the latest messages from Slack channels. Retrieve conversation history with
| ↳ `url_private` | string | Private download URL | | ↳ `url_private` | string | Private download URL |
| ↳ `permalink` | string | Permanent link to file | | ↳ `permalink` | string | Permanent link to file |
| ↳ `mode` | string | File mode | | ↳ `mode` | string | File mode |
| ↳ `id` | string | File ID |
| ↳ `mimetype` | string | MIME type |
| ↳ `size` | number | File size in bytes |
| ↳ `url_private` | string | Private download URL |
| ↳ `permalink` | string | Permanent link to message |
| ↳ `mode` | string | File mode |
| ↳ `attachments` | array | Array of legacy attachments | | ↳ `attachments` | array | Array of legacy attachments |
| ↳ `blocks` | array | Array of Block Kit blocks | | ↳ `blocks` | array | Array of Block Kit blocks |
| ↳ `edited` | object | Edit information if message was edited | | ↳ `edited` | object | Edit information if message was edited |
| ↳ `user` | string | User ID who edited | | ↳ `user` | string | User ID who edited |
| ↳ `ts` | string | Edit timestamp | | ↳ `ts` | string | Edit timestamp |
| ↳ `permalink` | string | Permanent link to message |
### `slack_get_message` ### `slack_get_message`
@@ -211,9 +203,9 @@ Retrieve a specific message by its timestamp. Useful for getting a thread parent
| --------- | ---- | ----------- | | --------- | ---- | ----------- |
| `message` | object | The retrieved message object | | `message` | object | The retrieved message object |
| ↳ `type` | string | Message type | | ↳ `type` | string | Message type |
| ↳ `ts` | string | Edit timestamp | | ↳ `ts` | string | Message timestamp |
| ↳ `text` | string | Message text content | | ↳ `text` | string | Message text content |
| ↳ `user` | string | User ID who edited | | ↳ `user` | string | User ID who sent the message |
| ↳ `bot_id` | string | Bot ID if sent by a bot | | ↳ `bot_id` | string | Bot ID if sent by a bot |
| ↳ `username` | string | Display username | | ↳ `username` | string | Display username |
| ↳ `channel` | string | Channel ID | | ↳ `channel` | string | Channel ID |
@@ -228,9 +220,6 @@ Retrieve a specific message by its timestamp. Useful for getting a thread parent
| ↳ `name` | string | Emoji name | | ↳ `name` | string | Emoji name |
| ↳ `count` | number | Number of reactions | | ↳ `count` | number | Number of reactions |
| ↳ `users` | array | User IDs who reacted | | ↳ `users` | array | User IDs who reacted |
| ↳ `name` | string | File name |
| ↳ `count` | number | Number of reactions |
| ↳ `users` | array | User IDs who reacted |
| ↳ `is_starred` | boolean | Whether message is starred | | ↳ `is_starred` | boolean | Whether message is starred |
| ↳ `pinned_to` | array | Channel IDs where message is pinned | | ↳ `pinned_to` | array | Channel IDs where message is pinned |
| ↳ `files` | array | Files attached to message | | ↳ `files` | array | Files attached to message |
@@ -240,16 +229,12 @@ Retrieve a specific message by its timestamp. Useful for getting a thread parent
| ↳ `size` | number | File size in bytes | | ↳ `size` | number | File size in bytes |
| ↳ `url_private` | string | Private download URL | | ↳ `url_private` | string | Private download URL |
| ↳ `permalink` | string | Permanent link to file | | ↳ `permalink` | string | Permanent link to file |
| ↳ `id` | string | File ID |
| ↳ `mimetype` | string | MIME type |
| ↳ `size` | number | File size in bytes |
| ↳ `url_private` | string | Private download URL |
| ↳ `permalink` | string | Permanent link to message |
| ↳ `attachments` | array | Legacy attachments | | ↳ `attachments` | array | Legacy attachments |
| ↳ `blocks` | array | Block Kit blocks | | ↳ `blocks` | array | Block Kit blocks |
| ↳ `edited` | object | Edit information if message was edited | | ↳ `edited` | object | Edit information if message was edited |
| ↳ `user` | string | User ID who edited | | ↳ `user` | string | User ID who edited |
| ↳ `ts` | string | Edit timestamp | | ↳ `ts` | string | Edit timestamp |
| ↳ `permalink` | string | Permanent link to message |
### `slack_get_thread` ### `slack_get_thread`
@@ -283,17 +268,11 @@ Retrieve an entire thread including the parent message and all replies. Useful f
| ↳ `name` | string | Emoji name | | ↳ `name` | string | Emoji name |
| ↳ `count` | number | Number of reactions | | ↳ `count` | number | Number of reactions |
| ↳ `users` | array | User IDs who reacted | | ↳ `users` | array | User IDs who reacted |
| ↳ `name` | string | File name |
| ↳ `count` | number | Number of reactions |
| ↳ `users` | array | User IDs who reacted |
| ↳ `files` | array | Files attached to the parent message | | ↳ `files` | array | Files attached to the parent message |
| ↳ `id` | string | File ID | | ↳ `id` | string | File ID |
| ↳ `name` | string | File name | | ↳ `name` | string | File name |
| ↳ `mimetype` | string | MIME type | | ↳ `mimetype` | string | MIME type |
| ↳ `size` | number | File size in bytes | | ↳ `size` | number | File size in bytes |
| ↳ `id` | string | File ID |
| ↳ `mimetype` | string | MIME type |
| ↳ `size` | number | File size in bytes |
| `replies` | array | Array of reply messages in the thread \(excluding the parent\) | | `replies` | array | Array of reply messages in the thread \(excluding the parent\) |
| ↳ `ts` | string | Message timestamp | | ↳ `ts` | string | Message timestamp |
| ↳ `text` | string | Message text content | | ↳ `text` | string | Message text content |

View File

@@ -86,9 +86,6 @@ Run an autonomous web agent to complete tasks and extract structured data
| ↳ `type` | string | Type of action performed | | ↳ `type` | string | Type of action performed |
| ↳ `params` | object | Parameters used for the action | | ↳ `params` | object | Parameters used for the action |
| ↳ `result` | object | Result of the action | | ↳ `result` | object | Result of the action |
| ↳ `type` | string | Type of action performed |
| ↳ `params` | object | Parameters used for the action |
| ↳ `result` | object | Result of the action |
| `structuredOutput` | object | Extracted data matching the provided output schema | | `structuredOutput` | object | Extracted data matching the provided output schema |

View File

@@ -82,16 +82,11 @@ Send messages to Telegram channels or users through the Telegram Bot API. Enable
| ↳ `is_bot` | boolean | Whether the chat is a bot or not | | ↳ `is_bot` | boolean | Whether the chat is a bot or not |
| ↳ `first_name` | string | Chat username \(if available\) | | ↳ `first_name` | string | Chat username \(if available\) |
| ↳ `username` | string | Chat title \(for groups and channels\) | | ↳ `username` | string | Chat title \(for groups and channels\) |
| ↳ `id` | number | Bot user ID |
| ↳ `is_bot` | boolean | Whether the chat is a bot or not |
| ↳ `first_name` | string | Bot first name |
| ↳ `username` | string | Bot username |
| ↳ `chat` | object | Information about the bot that sent the message | | ↳ `chat` | object | Information about the bot that sent the message |
| ↳ `id` | number | Bot user ID | | ↳ `id` | number | Bot user ID |
| ↳ `first_name` | string | Bot first name | | ↳ `first_name` | string | Bot first name |
| ↳ `username` | string | Bot username | | ↳ `username` | string | Bot username |
| ↳ `type` | string | chat type private or channel | | ↳ `type` | string | chat type private or channel |
| ↳ `type` | string | chat type private or channel |
| ↳ `date` | number | Unix timestamp when message was sent | | ↳ `date` | number | Unix timestamp when message was sent |
| ↳ `text` | string | Text content of the sent message | | ↳ `text` | string | Text content of the sent message |
@@ -141,16 +136,11 @@ Send photos to Telegram channels or users through the Telegram Bot API.
| ↳ `is_bot` | boolean | Whether the chat is a bot or not | | ↳ `is_bot` | boolean | Whether the chat is a bot or not |
| ↳ `first_name` | string | Chat username \(if available\) | | ↳ `first_name` | string | Chat username \(if available\) |
| ↳ `username` | string | Chat title \(for groups and channels\) | | ↳ `username` | string | Chat title \(for groups and channels\) |
| ↳ `id` | number | Bot user ID |
| ↳ `is_bot` | boolean | Whether the chat is a bot or not |
| ↳ `first_name` | string | Bot first name |
| ↳ `username` | string | Bot username |
| ↳ `chat` | object | Information about the bot that sent the message | | ↳ `chat` | object | Information about the bot that sent the message |
| ↳ `id` | number | Bot user ID | | ↳ `id` | number | Bot user ID |
| ↳ `first_name` | string | Bot first name | | ↳ `first_name` | string | Bot first name |
| ↳ `username` | string | Bot username | | ↳ `username` | string | Bot username |
| ↳ `type` | string | Chat type \(private, group, supergroup, channel\) | | ↳ `type` | string | Chat type \(private, group, supergroup, channel\) |
| ↳ `type` | string | Chat type \(private, group, supergroup, channel\) |
| ↳ `date` | number | Unix timestamp when message was sent | | ↳ `date` | number | Unix timestamp when message was sent |
| ↳ `text` | string | Text content of the sent message \(if applicable\) | | ↳ `text` | string | Text content of the sent message \(if applicable\) |
| ↳ `photo` | array | List of photos included in the message | | ↳ `photo` | array | List of photos included in the message |
@@ -159,11 +149,6 @@ Send photos to Telegram channels or users through the Telegram Bot API.
| ↳ `file_size` | number | Size of the photo file in bytes | | ↳ `file_size` | number | Size of the photo file in bytes |
| ↳ `width` | number | Photo width in pixels | | ↳ `width` | number | Photo width in pixels |
| ↳ `height` | number | Photo height in pixels | | ↳ `height` | number | Photo height in pixels |
| ↳ `file_id` | string | Unique file ID of the photo |
| ↳ `file_unique_id` | string | Unique identifier for this file across different bots |
| ↳ `file_size` | number | Size of the photo file in bytes |
| ↳ `width` | number | Photo width in pixels |
| ↳ `height` | number | Photo height in pixels |
### `telegram_send_video` ### `telegram_send_video`
@@ -190,25 +175,26 @@ Send videos to Telegram channels or users through the Telegram Bot API.
| ↳ `is_bot` | boolean | Whether the chat is a bot or not | | ↳ `is_bot` | boolean | Whether the chat is a bot or not |
| ↳ `first_name` | string | Sender | | ↳ `first_name` | string | Sender |
| ↳ `username` | string | Sender | | ↳ `username` | string | Sender |
| ↳ `id` | number | Chat ID |
| ↳ `is_bot` | boolean | Whether the chat is a bot or not |
| ↳ `first_name` | string | Chat first name \(if private chat\) |
| ↳ `username` | string | Chat username \(for private or channels\) |
| ↳ `chat` | object | Information about the chat where message was sent | | ↳ `chat` | object | Information about the chat where message was sent |
| ↳ `id` | number | Chat ID | | ↳ `id` | number | Chat ID |
| ↳ `first_name` | string | Chat first name \(if private chat\) | | ↳ `first_name` | string | Chat first name \(if private chat\) |
| ↳ `username` | string | Chat username \(for private or channels\) | | ↳ `username` | string | Chat username \(for private or channels\) |
| ↳ `type` | string | Type of chat \(private, group, supergroup, or channel\) | | ↳ `type` | string | Type of chat \(private, group, supergroup, or channel\) |
| ↳ `type` | string | Type of chat \(private, group, supergroup, or channel\) |
| ↳ `date` | number | Unix timestamp when the message was sent | | ↳ `date` | number | Unix timestamp when the message was sent |
| ↳ `text` | string | Text content of the sent message \(if applicable\) | | ↳ `text` | string | Text content of the sent message \(if applicable\) |
| ↳ `format` | object | Media format information \(for videos, GIFs, etc.\) | | ↳ `format` | object | Media format information \(for videos, GIFs, etc.\) |
| ↳ `file_name` | string | Media file name | | ↳ `file_name` | string | Media file name |
| ↳ `mime_type` | string | Media MIME type | | ↳ `mime_type` | string | Media MIME type |
| ↳ `duration` | number | Duration of media in seconds | | ↳ `duration` | number | Duration of media in seconds |
| ↳ `width` | number | Media width in pixels |
| ↳ `height` | number | Media height in pixels |
| ↳ `thumbnail` | object | Thumbnail image details |
| ↳ `file_id` | string | Thumbnail file ID |
| ↳ `file_unique_id` | string | Unique thumbnail file identifier |
| ↳ `file_size` | number | Thumbnail file size in bytes |
| ↳ `width` | number | Thumbnail width in pixels | | ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels | | ↳ `height` | number | Thumbnail height in pixels |
| ↳ `thumbnail` | object | Thumbnail image details | | ↳ `thumb` | object | Secondary thumbnail details \(duplicate of thumbnail\) |
| ↳ `file_id` | string | Thumbnail file ID | | ↳ `file_id` | string | Thumbnail file ID |
| ↳ `file_unique_id` | string | Unique thumbnail file identifier | | ↳ `file_unique_id` | string | Unique thumbnail file identifier |
| ↳ `file_size` | number | Thumbnail file size in bytes | | ↳ `file_size` | number | Thumbnail file size in bytes |
@@ -217,32 +203,6 @@ Send videos to Telegram channels or users through the Telegram Bot API.
| ↳ `file_id` | string | Media file ID | | ↳ `file_id` | string | Media file ID |
| ↳ `file_unique_id` | string | Unique media file identifier | | ↳ `file_unique_id` | string | Unique media file identifier |
| ↳ `file_size` | number | Size of media file in bytes | | ↳ `file_size` | number | Size of media file in bytes |
| ↳ `thumb` | object | Secondary thumbnail details \(duplicate of thumbnail\) |
| ↳ `file_id` | string | Thumbnail file ID |
| ↳ `file_unique_id` | string | Unique thumbnail file identifier |
| ↳ `file_size` | number | Thumbnail file size in bytes |
| ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels |
| ↳ `file_name` | string | Document file name |
| ↳ `mime_type` | string | Document MIME type |
| ↳ `duration` | number | Duration of media in seconds |
| ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels |
| ↳ `thumbnail` | object | Document thumbnail information |
| ↳ `file_id` | string | Thumbnail file ID |
| ↳ `file_unique_id` | string | Unique thumbnail file identifier |
| ↳ `file_size` | number | Thumbnail file size in bytes |
| ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels |
| ↳ `file_id` | string | Document file ID |
| ↳ `file_unique_id` | string | Unique document file identifier |
| ↳ `file_size` | number | Size of document file in bytes |
| ↳ `thumb` | object | Duplicate thumbnail info \(used for compatibility\) |
| ↳ `file_id` | string | Thumbnail file ID |
| ↳ `file_unique_id` | string | Unique thumbnail file identifier |
| ↳ `file_size` | number | Thumbnail file size in bytes |
| ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels |
| ↳ `document` | object | Document file details if the message contains a document | | ↳ `document` | object | Document file details if the message contains a document |
| ↳ `file_name` | string | Document file name | | ↳ `file_name` | string | Document file name |
| ↳ `mime_type` | string | Document MIME type | | ↳ `mime_type` | string | Document MIME type |
@@ -252,17 +212,15 @@ Send videos to Telegram channels or users through the Telegram Bot API.
| ↳ `file_size` | number | Thumbnail file size in bytes | | ↳ `file_size` | number | Thumbnail file size in bytes |
| ↳ `width` | number | Thumbnail width in pixels | | ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels | | ↳ `height` | number | Thumbnail height in pixels |
| ↳ `file_id` | string | Document file ID |
| ↳ `file_unique_id` | string | Unique document file identifier |
| ↳ `file_size` | number | Size of document file in bytes |
| ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels |
| ↳ `thumb` | object | Duplicate thumbnail info \(used for compatibility\) | | ↳ `thumb` | object | Duplicate thumbnail info \(used for compatibility\) |
| ↳ `file_id` | string | Thumbnail file ID | | ↳ `file_id` | string | Thumbnail file ID |
| ↳ `file_unique_id` | string | Unique thumbnail file identifier | | ↳ `file_unique_id` | string | Unique thumbnail file identifier |
| ↳ `file_size` | number | Thumbnail file size in bytes | | ↳ `file_size` | number | Thumbnail file size in bytes |
| ↳ `width` | number | Thumbnail width in pixels | | ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels | | ↳ `height` | number | Thumbnail height in pixels |
| ↳ `file_id` | string | Document file ID |
| ↳ `file_unique_id` | string | Unique document file identifier |
| ↳ `file_size` | number | Size of document file in bytes |
### `telegram_send_audio` ### `telegram_send_audio`
@@ -289,16 +247,11 @@ Send audio files to Telegram channels or users through the Telegram Bot API.
| ↳ `is_bot` | boolean | Whether the chat is a bot or not | | ↳ `is_bot` | boolean | Whether the chat is a bot or not |
| ↳ `first_name` | string | Sender | | ↳ `first_name` | string | Sender |
| ↳ `username` | string | Sender | | ↳ `username` | string | Sender |
| ↳ `id` | number | Chat ID |
| ↳ `is_bot` | boolean | Whether the chat is a bot or not |
| ↳ `first_name` | string | Chat first name \(if private chat\) |
| ↳ `username` | string | Chat username \(for private or channels\) |
| ↳ `chat` | object | Information about the chat where the message was sent | | ↳ `chat` | object | Information about the chat where the message was sent |
| ↳ `id` | number | Chat ID | | ↳ `id` | number | Chat ID |
| ↳ `first_name` | string | Chat first name \(if private chat\) | | ↳ `first_name` | string | Chat first name \(if private chat\) |
| ↳ `username` | string | Chat username \(for private or channels\) | | ↳ `username` | string | Chat username \(for private or channels\) |
| ↳ `type` | string | Type of chat \(private, group, supergroup, or channel\) | | ↳ `type` | string | Type of chat \(private, group, supergroup, or channel\) |
| ↳ `type` | string | Type of chat \(private, group, supergroup, or channel\) |
| ↳ `date` | number | Unix timestamp when the message was sent | | ↳ `date` | number | Unix timestamp when the message was sent |
| ↳ `text` | string | Text content of the sent message \(if applicable\) | | ↳ `text` | string | Text content of the sent message \(if applicable\) |
| ↳ `audio` | object | Audio file details | | ↳ `audio` | object | Audio file details |
@@ -310,14 +263,6 @@ Send audio files to Telegram channels or users through the Telegram Bot API.
| ↳ `file_id` | string | Unique file identifier for this audio | | ↳ `file_id` | string | Unique file identifier for this audio |
| ↳ `file_unique_id` | string | Unique identifier across different bots for this file | | ↳ `file_unique_id` | string | Unique identifier across different bots for this file |
| ↳ `file_size` | number | Size of the audio file in bytes | | ↳ `file_size` | number | Size of the audio file in bytes |
| ↳ `duration` | number | Duration of the audio in seconds |
| ↳ `performer` | string | Performer of the audio |
| ↳ `title` | string | Title of the audio |
| ↳ `file_name` | string | Original filename of the audio |
| ↳ `mime_type` | string | MIME type of the audio file |
| ↳ `file_id` | string | Unique file identifier for this audio |
| ↳ `file_unique_id` | string | Unique identifier across different bots for this file |
| ↳ `file_size` | number | Size of the audio file in bytes |
### `telegram_send_animation` ### `telegram_send_animation`
@@ -344,25 +289,26 @@ Send animations (GIFs) to Telegram channels or users through the Telegram Bot AP
| ↳ `is_bot` | boolean | Whether the chat is a bot or not | | ↳ `is_bot` | boolean | Whether the chat is a bot or not |
| ↳ `first_name` | string | Sender | | ↳ `first_name` | string | Sender |
| ↳ `username` | string | Sender | | ↳ `username` | string | Sender |
| ↳ `id` | number | Chat ID |
| ↳ `is_bot` | boolean | Whether the chat is a bot or not |
| ↳ `first_name` | string | Chat first name \(if private chat\) |
| ↳ `username` | string | Chat username \(for private or channels\) |
| ↳ `chat` | object | Information about the chat where message was sent | | ↳ `chat` | object | Information about the chat where message was sent |
| ↳ `id` | number | Chat ID | | ↳ `id` | number | Chat ID |
| ↳ `first_name` | string | Chat first name \(if private chat\) | | ↳ `first_name` | string | Chat first name \(if private chat\) |
| ↳ `username` | string | Chat username \(for private or channels\) | | ↳ `username` | string | Chat username \(for private or channels\) |
| ↳ `type` | string | Type of chat \(private, group, supergroup, or channel\) | | ↳ `type` | string | Type of chat \(private, group, supergroup, or channel\) |
| ↳ `type` | string | Type of chat \(private, group, supergroup, or channel\) |
| ↳ `date` | number | Unix timestamp when the message was sent | | ↳ `date` | number | Unix timestamp when the message was sent |
| ↳ `text` | string | Text content of the sent message \(if applicable\) | | ↳ `text` | string | Text content of the sent message \(if applicable\) |
| ↳ `format` | object | Media format information \(for videos, GIFs, etc.\) | | ↳ `format` | object | Media format information \(for videos, GIFs, etc.\) |
| ↳ `file_name` | string | Media file name | | ↳ `file_name` | string | Media file name |
| ↳ `mime_type` | string | Media MIME type | | ↳ `mime_type` | string | Media MIME type |
| ↳ `duration` | number | Duration of media in seconds | | ↳ `duration` | number | Duration of media in seconds |
| ↳ `width` | number | Media width in pixels |
| ↳ `height` | number | Media height in pixels |
| ↳ `thumbnail` | object | Thumbnail image details |
| ↳ `file_id` | string | Thumbnail file ID |
| ↳ `file_unique_id` | string | Unique thumbnail file identifier |
| ↳ `file_size` | number | Thumbnail file size in bytes |
| ↳ `width` | number | Thumbnail width in pixels | | ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels | | ↳ `height` | number | Thumbnail height in pixels |
| ↳ `thumbnail` | object | Thumbnail image details | | ↳ `thumb` | object | Secondary thumbnail details \(duplicate of thumbnail\) |
| ↳ `file_id` | string | Thumbnail file ID | | ↳ `file_id` | string | Thumbnail file ID |
| ↳ `file_unique_id` | string | Unique thumbnail file identifier | | ↳ `file_unique_id` | string | Unique thumbnail file identifier |
| ↳ `file_size` | number | Thumbnail file size in bytes | | ↳ `file_size` | number | Thumbnail file size in bytes |
@@ -371,32 +317,6 @@ Send animations (GIFs) to Telegram channels or users through the Telegram Bot AP
| ↳ `file_id` | string | Media file ID | | ↳ `file_id` | string | Media file ID |
| ↳ `file_unique_id` | string | Unique media file identifier | | ↳ `file_unique_id` | string | Unique media file identifier |
| ↳ `file_size` | number | Size of media file in bytes | | ↳ `file_size` | number | Size of media file in bytes |
| ↳ `thumb` | object | Secondary thumbnail details \(duplicate of thumbnail\) |
| ↳ `file_id` | string | Thumbnail file ID |
| ↳ `file_unique_id` | string | Unique thumbnail file identifier |
| ↳ `file_size` | number | Thumbnail file size in bytes |
| ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels |
| ↳ `file_name` | string | Document file name |
| ↳ `mime_type` | string | Document MIME type |
| ↳ `duration` | number | Duration of media in seconds |
| ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels |
| ↳ `thumbnail` | object | Document thumbnail information |
| ↳ `file_id` | string | Thumbnail file ID |
| ↳ `file_unique_id` | string | Unique thumbnail file identifier |
| ↳ `file_size` | number | Thumbnail file size in bytes |
| ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels |
| ↳ `file_id` | string | Document file ID |
| ↳ `file_unique_id` | string | Unique document file identifier |
| ↳ `file_size` | number | Size of document file in bytes |
| ↳ `thumb` | object | Duplicate thumbnail info \(used for compatibility\) |
| ↳ `file_id` | string | Thumbnail file ID |
| ↳ `file_unique_id` | string | Unique thumbnail file identifier |
| ↳ `file_size` | number | Thumbnail file size in bytes |
| ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels |
| ↳ `document` | object | Document file details if the message contains a document | | ↳ `document` | object | Document file details if the message contains a document |
| ↳ `file_name` | string | Document file name | | ↳ `file_name` | string | Document file name |
| ↳ `mime_type` | string | Document MIME type | | ↳ `mime_type` | string | Document MIME type |
@@ -406,17 +326,15 @@ Send animations (GIFs) to Telegram channels or users through the Telegram Bot AP
| ↳ `file_size` | number | Thumbnail file size in bytes | | ↳ `file_size` | number | Thumbnail file size in bytes |
| ↳ `width` | number | Thumbnail width in pixels | | ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels | | ↳ `height` | number | Thumbnail height in pixels |
| ↳ `file_id` | string | Document file ID |
| ↳ `file_unique_id` | string | Unique document file identifier |
| ↳ `file_size` | number | Size of document file in bytes |
| ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels |
| ↳ `thumb` | object | Duplicate thumbnail info \(used for compatibility\) | | ↳ `thumb` | object | Duplicate thumbnail info \(used for compatibility\) |
| ↳ `file_id` | string | Thumbnail file ID | | ↳ `file_id` | string | Thumbnail file ID |
| ↳ `file_unique_id` | string | Unique thumbnail file identifier | | ↳ `file_unique_id` | string | Unique thumbnail file identifier |
| ↳ `file_size` | number | Thumbnail file size in bytes | | ↳ `file_size` | number | Thumbnail file size in bytes |
| ↳ `width` | number | Thumbnail width in pixels | | ↳ `width` | number | Thumbnail width in pixels |
| ↳ `height` | number | Thumbnail height in pixels | | ↳ `height` | number | Thumbnail height in pixels |
| ↳ `file_id` | string | Document file ID |
| ↳ `file_unique_id` | string | Unique document file identifier |
| ↳ `file_size` | number | Size of document file in bytes |
### `telegram_send_document` ### `telegram_send_document`
@@ -443,16 +361,11 @@ Send documents (PDF, ZIP, DOC, etc.) to Telegram channels or users through the T
| ↳ `is_bot` | boolean | Whether the chat is a bot or not | | ↳ `is_bot` | boolean | Whether the chat is a bot or not |
| ↳ `first_name` | string | Sender | | ↳ `first_name` | string | Sender |
| ↳ `username` | string | Sender | | ↳ `username` | string | Sender |
| ↳ `id` | number | Chat ID |
| ↳ `is_bot` | boolean | Whether the chat is a bot or not |
| ↳ `first_name` | string | Chat first name \(if private chat\) |
| ↳ `username` | string | Chat username \(for private or channels\) |
| ↳ `chat` | object | Information about the chat where message was sent | | ↳ `chat` | object | Information about the chat where message was sent |
| ↳ `id` | number | Chat ID | | ↳ `id` | number | Chat ID |
| ↳ `first_name` | string | Chat first name \(if private chat\) | | ↳ `first_name` | string | Chat first name \(if private chat\) |
| ↳ `username` | string | Chat username \(for private or channels\) | | ↳ `username` | string | Chat username \(for private or channels\) |
| ↳ `type` | string | Type of chat \(private, group, supergroup, or channel\) | | ↳ `type` | string | Type of chat \(private, group, supergroup, or channel\) |
| ↳ `type` | string | Type of chat \(private, group, supergroup, or channel\) |
| ↳ `date` | number | Unix timestamp when the message was sent | | ↳ `date` | number | Unix timestamp when the message was sent |
| ↳ `document` | object | Document file details | | ↳ `document` | object | Document file details |
| ↳ `file_name` | string | Document file name | | ↳ `file_name` | string | Document file name |
@@ -460,10 +373,5 @@ Send documents (PDF, ZIP, DOC, etc.) to Telegram channels or users through the T
| ↳ `file_id` | string | Document file ID | | ↳ `file_id` | string | Document file ID |
| ↳ `file_unique_id` | string | Unique document file identifier | | ↳ `file_unique_id` | string | Unique document file identifier |
| ↳ `file_size` | number | Size of document file in bytes | | ↳ `file_size` | number | Size of document file in bytes |
| ↳ `file_name` | string | Document file name |
| ↳ `mime_type` | string | Document MIME type |
| ↳ `file_id` | string | Document file ID |
| ↳ `file_unique_id` | string | Unique document file identifier |
| ↳ `file_size` | number | Size of document file in bytes |

View File

@@ -63,7 +63,7 @@ Parse documents using AWS Textract OCR and document analysis
| `blocks` | array | Array of Block objects containing detected text, tables, forms, and other elements | | `blocks` | array | Array of Block objects containing detected text, tables, forms, and other elements |
| ↳ `BlockType` | string | Type of block \(PAGE, LINE, WORD, TABLE, CELL, KEY_VALUE_SET, etc.\) | | ↳ `BlockType` | string | Type of block \(PAGE, LINE, WORD, TABLE, CELL, KEY_VALUE_SET, etc.\) |
| ↳ `Id` | string | Unique identifier for the block | | ↳ `Id` | string | Unique identifier for the block |
| ↳ `Text` | string | Query text | | ↳ `Text` | string | The text content \(for LINE and WORD blocks\) |
| ↳ `TextType` | string | Type of text \(PRINTED or HANDWRITING\) | | ↳ `TextType` | string | Type of text \(PRINTED or HANDWRITING\) |
| ↳ `Confidence` | number | Confidence score \(0-100\) | | ↳ `Confidence` | number | Confidence score \(0-100\) |
| ↳ `Page` | number | Page number | | ↳ `Page` | number | Page number |
@@ -73,34 +73,12 @@ Parse documents using AWS Textract OCR and document analysis
| ↳ `Left` | number | Left position as ratio of document width | | ↳ `Left` | number | Left position as ratio of document width |
| ↳ `Top` | number | Top position as ratio of document height | | ↳ `Top` | number | Top position as ratio of document height |
| ↳ `Width` | number | Width as ratio of document width | | ↳ `Width` | number | Width as ratio of document width |
| ↳ `Height` | number | Height as ratio of document height |
| ↳ `Left` | number | Left position as ratio of document width |
| ↳ `Top` | number | Top position as ratio of document height |
| ↳ `Width` | number | Width as ratio of document width |
| ↳ `Polygon` | array | Polygon coordinates | | ↳ `Polygon` | array | Polygon coordinates |
| ↳ `X` | number | X coordinate | | ↳ `X` | number | X coordinate |
| ↳ `Y` | number | Y coordinate | | ↳ `Y` | number | Y coordinate |
| ↳ `X` | number | X coordinate |
| ↳ `Y` | number | Y coordinate |
| ↳ `BoundingBox` | object | Height as ratio of document height |
| ↳ `Height` | number | Height as ratio of document height |
| ↳ `Left` | number | Left position as ratio of document width |
| ↳ `Top` | number | Top position as ratio of document height |
| ↳ `Width` | number | Width as ratio of document width |
| ↳ `Height` | number | Height as ratio of document height |
| ↳ `Left` | number | Left position as ratio of document width |
| ↳ `Top` | number | Top position as ratio of document height |
| ↳ `Width` | number | Width as ratio of document width |
| ↳ `Polygon` | array | Polygon coordinates |
| ↳ `X` | number | X coordinate |
| ↳ `Y` | number | Y coordinate |
| ↳ `X` | number | X coordinate |
| ↳ `Y` | number | Y coordinate |
| ↳ `Relationships` | array | Relationships to other blocks | | ↳ `Relationships` | array | Relationships to other blocks |
| ↳ `Type` | string | Relationship type \(CHILD, VALUE, ANSWER, etc.\) | | ↳ `Type` | string | Relationship type \(CHILD, VALUE, ANSWER, etc.\) |
| ↳ `Ids` | array | IDs of related blocks | | ↳ `Ids` | array | IDs of related blocks |
| ↳ `Type` | string | Relationship type \(CHILD, VALUE, ANSWER, etc.\) |
| ↳ `Ids` | array | IDs of related blocks |
| ↳ `EntityTypes` | array | Entity types for KEY_VALUE_SET \(KEY or VALUE\) | | ↳ `EntityTypes` | array | Entity types for KEY_VALUE_SET \(KEY or VALUE\) |
| ↳ `SelectionStatus` | string | For checkboxes: SELECTED or NOT_SELECTED | | ↳ `SelectionStatus` | string | For checkboxes: SELECTED or NOT_SELECTED |
| ↳ `RowIndex` | number | Row index for table cells | | ↳ `RowIndex` | number | Row index for table cells |
@@ -111,8 +89,6 @@ Parse documents using AWS Textract OCR and document analysis
| ↳ `Text` | string | Query text | | ↳ `Text` | string | Query text |
| ↳ `Alias` | string | Query alias | | ↳ `Alias` | string | Query alias |
| ↳ `Pages` | array | Pages to search | | ↳ `Pages` | array | Pages to search |
| ↳ `Alias` | string | Query alias |
| ↳ `Pages` | array | Pages to search |
| `documentMetadata` | object | Metadata about the analyzed document | | `documentMetadata` | object | Metadata about the analyzed document |
| ↳ `pages` | number | Number of pages in the document | | ↳ `pages` | number | Number of pages in the document |
| `modelVersion` | string | Version of the Textract model used for processing | | `modelVersion` | string | Version of the Textract model used for processing |

View File

@@ -109,12 +109,6 @@ Retrieve insights and analytics for Typeform forms
| ↳ `responses_count` | number | Number of responses from this platform | | ↳ `responses_count` | number | Number of responses from this platform |
| ↳ `total_visits` | number | Total visits from this platform | | ↳ `total_visits` | number | Total visits from this platform |
| ↳ `unique_visits` | number | Unique visits from this platform | | ↳ `unique_visits` | number | Unique visits from this platform |
| ↳ `average_time` | number | Overall average completion time |
| ↳ `completion_rate` | number | Overall completion rate |
| ↳ `platform` | string | Platform name \(e.g., desktop, mobile\) |
| ↳ `responses_count` | number | Total number of responses |
| ↳ `total_visits` | number | Total number of visits |
| ↳ `unique_visits` | number | Total number of unique visits |
| ↳ `summary` | object | Overall average completion time | | ↳ `summary` | object | Overall average completion time |
| ↳ `average_time` | number | Overall average completion time | | ↳ `average_time` | number | Overall average completion time |
| ↳ `completion_rate` | number | Overall completion rate | | ↳ `completion_rate` | number | Overall completion rate |

View File

@@ -56,9 +56,6 @@ Read content from a Wealthbox note
| ↳ `itemId` | string | ID of the note | | ↳ `itemId` | string | ID of the note |
| ↳ `noteId` | string | ID of the note | | ↳ `noteId` | string | ID of the note |
| ↳ `itemType` | string | Type of item \(note\) | | ↳ `itemType` | string | Type of item \(note\) |
| ↳ `itemId` | string | ID of the note |
| ↳ `noteId` | string | ID of the note |
| ↳ `itemType` | string | Type of item \(note\) |
### `wealthbox_write_note` ### `wealthbox_write_note`
@@ -83,9 +80,6 @@ Create or update a Wealthbox note
| ↳ `itemId` | string | ID of the created/updated note | | ↳ `itemId` | string | ID of the created/updated note |
| ↳ `noteId` | string | ID of the created/updated note | | ↳ `noteId` | string | ID of the created/updated note |
| ↳ `itemType` | string | Type of item \(note\) | | ↳ `itemType` | string | Type of item \(note\) |
| ↳ `itemId` | string | ID of the created/updated note |
| ↳ `noteId` | string | ID of the created/updated note |
| ↳ `itemType` | string | Type of item \(note\) |
### `wealthbox_read_contact` ### `wealthbox_read_contact`
@@ -109,9 +103,6 @@ Read content from a Wealthbox contact
| ↳ `itemId` | string | ID of the contact | | ↳ `itemId` | string | ID of the contact |
| ↳ `contactId` | string | ID of the contact | | ↳ `contactId` | string | ID of the contact |
| ↳ `itemType` | string | Type of item \(contact\) | | ↳ `itemType` | string | Type of item \(contact\) |
| ↳ `itemId` | string | ID of the contact |
| ↳ `contactId` | string | ID of the contact |
| ↳ `itemType` | string | Type of item \(contact\) |
### `wealthbox_write_contact` ### `wealthbox_write_contact`
@@ -138,9 +129,6 @@ Create a new Wealthbox contact
| ↳ `itemId` | string | ID of the created/updated contact | | ↳ `itemId` | string | ID of the created/updated contact |
| ↳ `contactId` | string | ID of the created/updated contact | | ↳ `contactId` | string | ID of the created/updated contact |
| ↳ `itemType` | string | Type of item \(contact\) | | ↳ `itemType` | string | Type of item \(contact\) |
| ↳ `itemId` | string | ID of the created/updated contact |
| ↳ `contactId` | string | ID of the created/updated contact |
| ↳ `itemType` | string | Type of item \(contact\) |
### `wealthbox_read_task` ### `wealthbox_read_task`
@@ -164,9 +152,6 @@ Read content from a Wealthbox task
| ↳ `itemId` | string | ID of the task | | ↳ `itemId` | string | ID of the task |
| ↳ `taskId` | string | ID of the task | | ↳ `taskId` | string | ID of the task |
| ↳ `itemType` | string | Type of item \(task\) | | ↳ `itemType` | string | Type of item \(task\) |
| ↳ `itemId` | string | ID of the task |
| ↳ `taskId` | string | ID of the task |
| ↳ `itemType` | string | Type of item \(task\) |
### `wealthbox_write_task` ### `wealthbox_write_task`
@@ -193,8 +178,5 @@ Create or update a Wealthbox task
| ↳ `itemId` | string | ID of the created/updated task | | ↳ `itemId` | string | ID of the created/updated task |
| ↳ `taskId` | string | ID of the created/updated task | | ↳ `taskId` | string | ID of the created/updated task |
| ↳ `itemType` | string | Type of item \(task\) | | ↳ `itemType` | string | Type of item \(task\) |
| ↳ `itemId` | string | ID of the created/updated task |
| ↳ `taskId` | string | ID of the created/updated task |
| ↳ `itemType` | string | Type of item \(task\) |

View File

@@ -61,8 +61,6 @@ Post new tweets, reply to tweets, or create polls on X (Twitter)
| ↳ `attachments` | object | Media or poll attachments | | ↳ `attachments` | object | Media or poll attachments |
| ↳ `mediaKeys` | array | Media attachment keys | | ↳ `mediaKeys` | array | Media attachment keys |
| ↳ `pollId` | string | Poll ID if poll attached | | ↳ `pollId` | string | Poll ID if poll attached |
| ↳ `mediaKeys` | array | Media attachment keys |
| ↳ `pollId` | string | Poll ID if poll attached |
### `x_read` ### `x_read`
@@ -139,8 +137,5 @@ Get user profile information
| ↳ `followersCount` | number | Number of followers | | ↳ `followersCount` | number | Number of followers |
| ↳ `followingCount` | number | Number of users following | | ↳ `followingCount` | number | Number of users following |
| ↳ `tweetCount` | number | Total number of tweets | | ↳ `tweetCount` | number | Total number of tweets |
| ↳ `followersCount` | number | Number of followers |
| ↳ `followingCount` | number | Number of users following |
| ↳ `tweetCount` | number | Total number of tweets |

View File

@@ -35,8 +35,7 @@ const AutoLayoutRequestSchema = z.object({
}) })
.optional() .optional()
.default({}), .default({}),
// Optional: if provided, use these blocks instead of loading from DB gridSize: z.number().min(0).max(50).optional(),
// This allows using blocks with live measurements from the UI
blocks: z.record(z.any()).optional(), blocks: z.record(z.any()).optional(),
edges: z.array(z.any()).optional(), edges: z.array(z.any()).optional(),
loops: z.record(z.any()).optional(), loops: z.record(z.any()).optional(),
@@ -53,7 +52,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
const { id: workflowId } = await params const { id: workflowId } = await params
try { try {
// Get the session
const session = await getSession() const session = await getSession()
if (!session?.user?.id) { if (!session?.user?.id) {
logger.warn(`[${requestId}] Unauthorized autolayout attempt for workflow ${workflowId}`) logger.warn(`[${requestId}] Unauthorized autolayout attempt for workflow ${workflowId}`)
@@ -62,7 +60,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
const userId = session.user.id const userId = session.user.id
// Parse request body
const body = await request.json() const body = await request.json()
const layoutOptions = AutoLayoutRequestSchema.parse(body) const layoutOptions = AutoLayoutRequestSchema.parse(body)
@@ -70,7 +67,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
userId, userId,
}) })
// Fetch the workflow to check ownership/access
const accessContext = await getWorkflowAccessContext(workflowId, userId) const accessContext = await getWorkflowAccessContext(workflowId, userId)
const workflowData = accessContext?.workflow const workflowData = accessContext?.workflow
@@ -79,7 +75,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
return NextResponse.json({ error: 'Workflow not found' }, { status: 404 }) return NextResponse.json({ error: 'Workflow not found' }, { status: 404 })
} }
// Check if user has permission to update this workflow
const canUpdate = const canUpdate =
accessContext?.isOwner || accessContext?.isOwner ||
(workflowData.workspaceId (workflowData.workspaceId
@@ -94,8 +89,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
return NextResponse.json({ error: 'Access denied' }, { status: 403 }) return NextResponse.json({ error: 'Access denied' }, { status: 403 })
} }
// Use provided blocks/edges if available (with live measurements from UI),
// otherwise load from database
let currentWorkflowData: NormalizedWorkflowData | null let currentWorkflowData: NormalizedWorkflowData | null
if (layoutOptions.blocks && layoutOptions.edges) { if (layoutOptions.blocks && layoutOptions.edges) {
@@ -125,6 +118,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
y: layoutOptions.padding?.y ?? DEFAULT_LAYOUT_PADDING.y, y: layoutOptions.padding?.y ?? DEFAULT_LAYOUT_PADDING.y,
}, },
alignment: layoutOptions.alignment, alignment: layoutOptions.alignment,
gridSize: layoutOptions.gridSize,
} }
const layoutResult = applyAutoLayout( const layoutResult = applyAutoLayout(

View File

@@ -1,108 +0,0 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { generateRequestId } from '@/lib/core/utils/request'
import { applyAutoLayout } from '@/lib/workflows/autolayout'
import {
DEFAULT_HORIZONTAL_SPACING,
DEFAULT_LAYOUT_PADDING,
DEFAULT_VERTICAL_SPACING,
} from '@/lib/workflows/autolayout/constants'
const logger = createLogger('YamlAutoLayoutAPI')
const AutoLayoutRequestSchema = z.object({
workflowState: z.object({
blocks: z.record(z.any()),
edges: z.array(z.any()),
loops: z.record(z.any()).optional().default({}),
parallels: z.record(z.any()).optional().default({}),
}),
options: z
.object({
spacing: z
.object({
horizontal: z.number().optional(),
vertical: z.number().optional(),
})
.optional(),
alignment: z.enum(['start', 'center', 'end']).optional(),
padding: z
.object({
x: z.number().optional(),
y: z.number().optional(),
})
.optional(),
})
.optional(),
})
export async function POST(request: NextRequest) {
const requestId = generateRequestId()
try {
const body = await request.json()
const { workflowState, options } = AutoLayoutRequestSchema.parse(body)
logger.info(`[${requestId}] Applying auto layout`, {
blockCount: Object.keys(workflowState.blocks).length,
edgeCount: workflowState.edges.length,
})
const autoLayoutOptions = {
horizontalSpacing: options?.spacing?.horizontal ?? DEFAULT_HORIZONTAL_SPACING,
verticalSpacing: options?.spacing?.vertical ?? DEFAULT_VERTICAL_SPACING,
padding: {
x: options?.padding?.x ?? DEFAULT_LAYOUT_PADDING.x,
y: options?.padding?.y ?? DEFAULT_LAYOUT_PADDING.y,
},
alignment: options?.alignment ?? 'center',
}
const layoutResult = applyAutoLayout(
workflowState.blocks,
workflowState.edges,
autoLayoutOptions
)
if (!layoutResult.success || !layoutResult.blocks) {
logger.error(`[${requestId}] Auto layout failed:`, {
error: layoutResult.error,
})
return NextResponse.json(
{
success: false,
errors: [layoutResult.error || 'Unknown auto layout error'],
},
{ status: 500 }
)
}
logger.info(`[${requestId}] Auto layout completed successfully:`, {
success: true,
blockCount: Object.keys(layoutResult.blocks).length,
})
const transformedResponse = {
success: true,
workflowState: {
blocks: layoutResult.blocks,
edges: workflowState.edges,
loops: workflowState.loops || {},
parallels: workflowState.parallels || {},
},
}
return NextResponse.json(transformedResponse)
} catch (error) {
logger.error(`[${requestId}] Auto layout failed:`, error)
return NextResponse.json(
{
success: false,
errors: [error instanceof Error ? error.message : 'Unknown auto layout error'],
},
{ status: 500 }
)
}
}

View File

@@ -6,7 +6,6 @@ import { useRouter } from 'next/navigation'
import { import {
Badge, Badge,
Button, Button,
Code,
Input, Input,
Label, Label,
Table, Table,
@@ -777,15 +776,6 @@ export default function ResumeExecutionPage({
refreshSelectedDetail, refreshSelectedDetail,
]) ])
const pauseResponsePreview = useMemo(() => {
if (!selectedDetail?.pausePoint.response?.data) return '{}'
try {
return JSON.stringify(selectedDetail.pausePoint.response.data, null, 2)
} catch {
return String(selectedDetail.pausePoint.response.data)
}
}, [selectedDetail])
const isFormComplete = useMemo(() => { const isFormComplete = useMemo(() => {
if (!isHumanMode || !hasInputFormat) return true if (!isHumanMode || !hasInputFormat) return true
return inputFormatFields.every((field) => { return inputFormatFields.every((field) => {
@@ -1155,10 +1145,12 @@ export default function ResumeExecutionPage({
borderBottom: '1px solid var(--border)', borderBottom: '1px solid var(--border)',
}} }}
> >
<Label>Pause Data</Label> <Label>Display Data</Label>
</div> </div>
<div style={{ padding: '16px' }}> <div style={{ padding: '16px' }}>
<Code.Viewer code={pauseResponsePreview} language='json' /> <p style={{ fontSize: '13px', color: 'var(--text-muted)' }}>
No display data configured
</p>
</div> </div>
</div> </div>
)} )}

View File

@@ -1183,19 +1183,6 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
const outputPaths = getBlockOutputPaths(sourceBlock.type, mergedSubBlocks, true) const outputPaths = getBlockOutputPaths(sourceBlock.type, mergedSubBlocks, true)
blockTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`) blockTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
} }
} else if (sourceBlock.type === 'approval') {
const dynamicOutputs = getBlockOutputPaths(sourceBlock.type, mergedSubBlocks)
const isSelfReference = activeSourceBlockId === blockId
if (dynamicOutputs.length > 0) {
const allTags = dynamicOutputs.map((path) => `${normalizedBlockName}.${path}`)
blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags
} else {
const outputPaths = getBlockOutputPaths(sourceBlock.type, mergedSubBlocks)
const allTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags
}
} else if (sourceBlock.type === 'human_in_the_loop') { } else if (sourceBlock.type === 'human_in_the_loop') {
const dynamicOutputs = getBlockOutputPaths(sourceBlock.type, mergedSubBlocks) const dynamicOutputs = getBlockOutputPaths(sourceBlock.type, mergedSubBlocks)
@@ -1400,13 +1387,8 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
if (!accessibleBlock) continue if (!accessibleBlock) continue
// Skip the current block - blocks cannot reference their own outputs // Skip the current block - blocks cannot reference their own outputs
// Exception: approval and human_in_the_loop blocks can reference their own outputs // Exception: human_in_the_loop blocks can reference their own outputs (url, resumeEndpoint)
if ( if (accessibleBlockId === blockId && accessibleBlock.type !== 'human_in_the_loop') continue
accessibleBlockId === blockId &&
accessibleBlock.type !== 'approval' &&
accessibleBlock.type !== 'human_in_the_loop'
)
continue
const blockConfig = getBlock(accessibleBlock.type) const blockConfig = getBlock(accessibleBlock.type)
@@ -1520,19 +1502,6 @@ export const TagDropdown: React.FC<TagDropdownProps> = ({
const outputPaths = getBlockOutputPaths(accessibleBlock.type, mergedSubBlocks, true) const outputPaths = getBlockOutputPaths(accessibleBlock.type, mergedSubBlocks, true)
blockTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`) blockTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
} }
} else if (accessibleBlock.type === 'approval') {
const dynamicOutputs = getBlockOutputPaths(accessibleBlock.type, mergedSubBlocks)
const isSelfReference = accessibleBlockId === blockId
if (dynamicOutputs.length > 0) {
const allTags = dynamicOutputs.map((path) => `${normalizedBlockName}.${path}`)
blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags
} else {
const outputPaths = getBlockOutputPaths(accessibleBlock.type, mergedSubBlocks)
const allTags = outputPaths.map((path) => `${normalizedBlockName}.${path}`)
blockTags = isSelfReference ? allTags.filter((tag) => tag.endsWith('.url')) : allTags
}
} else if (accessibleBlock.type === 'human_in_the_loop') { } else if (accessibleBlock.type === 'human_in_the_loop') {
const dynamicOutputs = getBlockOutputPaths(accessibleBlock.type, mergedSubBlocks) const dynamicOutputs = getBlockOutputPaths(accessibleBlock.type, mergedSubBlocks)

View File

@@ -3,6 +3,7 @@ import { createLogger } from '@sim/logger'
import { useReactFlow } from 'reactflow' import { useReactFlow } from 'reactflow'
import type { AutoLayoutOptions } from '@/app/workspace/[workspaceId]/w/[workflowId]/utils/auto-layout-utils' import type { AutoLayoutOptions } from '@/app/workspace/[workspaceId]/w/[workflowId]/utils/auto-layout-utils'
import { applyAutoLayoutAndUpdateStore as applyAutoLayoutStandalone } from '@/app/workspace/[workspaceId]/w/[workflowId]/utils/auto-layout-utils' import { applyAutoLayoutAndUpdateStore as applyAutoLayoutStandalone } from '@/app/workspace/[workspaceId]/w/[workflowId]/utils/auto-layout-utils'
import { useSnapToGridSize } from '@/hooks/queries/general-settings'
import { useCanvasViewport } from '@/hooks/use-canvas-viewport' import { useCanvasViewport } from '@/hooks/use-canvas-viewport'
export type { AutoLayoutOptions } export type { AutoLayoutOptions }
@@ -13,21 +14,28 @@ const logger = createLogger('useAutoLayout')
* Hook providing auto-layout functionality for workflows. * Hook providing auto-layout functionality for workflows.
* Binds workflowId context and provides memoized callback for React components. * Binds workflowId context and provides memoized callback for React components.
* Includes automatic fitView animation after successful layout. * Includes automatic fitView animation after successful layout.
* Automatically uses the user's snap-to-grid setting for grid-aligned layout.
* *
* Note: This hook requires a ReactFlowProvider ancestor. * Note: This hook requires a ReactFlowProvider ancestor.
*/ */
export function useAutoLayout(workflowId: string | null) { export function useAutoLayout(workflowId: string | null) {
const reactFlowInstance = useReactFlow() const reactFlowInstance = useReactFlow()
const { fitViewToBounds } = useCanvasViewport(reactFlowInstance) const { fitViewToBounds } = useCanvasViewport(reactFlowInstance)
const snapToGridSize = useSnapToGridSize()
const applyAutoLayoutAndUpdateStore = useCallback( const applyAutoLayoutAndUpdateStore = useCallback(
async (options: AutoLayoutOptions = {}) => { async (options: AutoLayoutOptions = {}) => {
if (!workflowId) { if (!workflowId) {
return { success: false, error: 'No workflow ID provided' } return { success: false, error: 'No workflow ID provided' }
} }
return applyAutoLayoutStandalone(workflowId, options) // Include gridSize from user's snap-to-grid setting
const optionsWithGrid: AutoLayoutOptions = {
...options,
gridSize: options.gridSize ?? (snapToGridSize > 0 ? snapToGridSize : undefined),
}
return applyAutoLayoutStandalone(workflowId, optionsWithGrid)
}, },
[workflowId] [workflowId, snapToGridSize]
) )
/** /**

View File

@@ -21,6 +21,7 @@ export interface AutoLayoutOptions {
x?: number x?: number
y?: number y?: number
} }
gridSize?: number
} }
/** /**
@@ -62,6 +63,7 @@ export async function applyAutoLayoutAndUpdateStore(
x: options.padding?.x ?? DEFAULT_LAYOUT_PADDING.x, x: options.padding?.x ?? DEFAULT_LAYOUT_PADDING.x,
y: options.padding?.y ?? DEFAULT_LAYOUT_PADDING.y, y: options.padding?.y ?? DEFAULT_LAYOUT_PADDING.y,
}, },
gridSize: options.gridSize,
} }
// Call the autolayout API route // Call the autolayout API route

View File

@@ -769,7 +769,13 @@ Example 3 (Array Input):
outputs: { outputs: {
content: { type: 'string', description: 'Generated response content' }, content: { type: 'string', description: 'Generated response content' },
model: { type: 'string', description: 'Model used for generation' }, model: { type: 'string', description: 'Model used for generation' },
tokens: { type: 'any', description: 'Token usage statistics' }, tokens: { type: 'json', description: 'Token usage statistics' },
toolCalls: { type: 'any', description: 'Tool calls made' }, toolCalls: { type: 'json', description: 'Tool calls made' },
providerTiming: {
type: 'json',
description: 'Provider timing information',
hiddenFromDisplay: true,
},
cost: { type: 'number', description: 'Cost of the API call', hiddenFromDisplay: true },
}, },
} }

View File

@@ -0,0 +1,393 @@
import { ClerkIcon } from '@/components/icons'
import type { BlockConfig } from '@/blocks/types'
import type { ClerkResponse } from '@/tools/clerk/types'
export const ClerkBlock: BlockConfig<ClerkResponse> = {
type: 'clerk',
name: 'Clerk',
description: 'Manage users, organizations, and sessions in Clerk',
longDescription:
'Integrate Clerk authentication and user management into your workflow. Create, update, delete, and list users. Manage organizations and their memberships. Monitor and control user sessions.',
docsLink: 'https://docs.sim.ai/tools/clerk',
category: 'tools',
bgColor: '#131316',
icon: ClerkIcon,
subBlocks: [
{
id: 'operation',
title: 'Operation',
type: 'dropdown',
options: [
{ label: 'List Users', id: 'clerk_list_users' },
{ label: 'Get User', id: 'clerk_get_user' },
{ label: 'Create User', id: 'clerk_create_user' },
{ label: 'Update User', id: 'clerk_update_user' },
{ label: 'Delete User', id: 'clerk_delete_user' },
{ label: 'List Organizations', id: 'clerk_list_organizations' },
{ label: 'Get Organization', id: 'clerk_get_organization' },
{ label: 'Create Organization', id: 'clerk_create_organization' },
{ label: 'List Sessions', id: 'clerk_list_sessions' },
{ label: 'Get Session', id: 'clerk_get_session' },
{ label: 'Revoke Session', id: 'clerk_revoke_session' },
],
value: () => 'clerk_list_users',
},
{
id: 'secretKey',
title: 'Secret Key',
type: 'short-input',
password: true,
placeholder: 'sk_live_... or sk_test_...',
required: true,
},
// List Users params
{
id: 'query',
title: 'Search Query',
type: 'short-input',
placeholder: 'Search by email, phone, username, or name',
condition: { field: 'operation', value: 'clerk_list_users' },
},
{
id: 'emailAddressFilter',
title: 'Email Filter',
type: 'short-input',
placeholder: 'Filter by email (comma-separated)',
condition: { field: 'operation', value: 'clerk_list_users' },
},
{
id: 'usernameFilter',
title: 'Username Filter',
type: 'short-input',
placeholder: 'Filter by username (comma-separated)',
condition: { field: 'operation', value: 'clerk_list_users' },
},
// Get User params
{
id: 'userId',
title: 'User ID',
type: 'short-input',
placeholder: 'user_...',
condition: {
field: 'operation',
value: ['clerk_get_user', 'clerk_update_user', 'clerk_delete_user'],
},
required: {
field: 'operation',
value: ['clerk_get_user', 'clerk_update_user', 'clerk_delete_user'],
},
},
// Create/Update User params
{
id: 'emailAddress',
title: 'Email Address',
type: 'short-input',
placeholder: 'user@example.com (comma-separated for multiple)',
condition: { field: 'operation', value: 'clerk_create_user' },
},
{
id: 'phoneNumber',
title: 'Phone Number',
type: 'short-input',
placeholder: '+1234567890 (comma-separated for multiple)',
condition: { field: 'operation', value: 'clerk_create_user' },
},
{
id: 'username',
title: 'Username',
type: 'short-input',
placeholder: 'johndoe',
condition: { field: 'operation', value: ['clerk_create_user', 'clerk_update_user'] },
},
{
id: 'password',
title: 'Password',
type: 'short-input',
password: true,
placeholder: 'Minimum 8 characters',
condition: { field: 'operation', value: ['clerk_create_user', 'clerk_update_user'] },
},
{
id: 'firstName',
title: 'First Name',
type: 'short-input',
placeholder: 'John',
condition: { field: 'operation', value: ['clerk_create_user', 'clerk_update_user'] },
},
{
id: 'lastName',
title: 'Last Name',
type: 'short-input',
placeholder: 'Doe',
condition: { field: 'operation', value: ['clerk_create_user', 'clerk_update_user'] },
},
{
id: 'externalId',
title: 'External ID',
type: 'short-input',
placeholder: 'Your system user ID',
condition: { field: 'operation', value: ['clerk_create_user', 'clerk_update_user'] },
},
{
id: 'publicMetadata',
title: 'Public Metadata',
type: 'code',
language: 'json',
placeholder: '{"role": "admin"}',
condition: { field: 'operation', value: ['clerk_create_user', 'clerk_update_user'] },
},
{
id: 'privateMetadata',
title: 'Private Metadata',
type: 'code',
language: 'json',
placeholder: '{"internalId": "123"}',
condition: { field: 'operation', value: ['clerk_create_user', 'clerk_update_user'] },
},
// Organization params
{
id: 'orgQuery',
title: 'Search Query',
type: 'short-input',
placeholder: 'Search by name, ID, or slug',
condition: { field: 'operation', value: 'clerk_list_organizations' },
},
{
id: 'includeMembersCount',
title: 'Include Members Count',
type: 'switch',
condition: { field: 'operation', value: 'clerk_list_organizations' },
},
{
id: 'organizationId',
title: 'Organization ID',
type: 'short-input',
placeholder: 'org_... or slug',
condition: { field: 'operation', value: 'clerk_get_organization' },
required: { field: 'operation', value: 'clerk_get_organization' },
},
{
id: 'orgName',
title: 'Organization Name',
type: 'short-input',
placeholder: 'Acme Corp',
condition: { field: 'operation', value: 'clerk_create_organization' },
required: { field: 'operation', value: 'clerk_create_organization' },
},
{
id: 'createdBy',
title: 'Creator User ID',
type: 'short-input',
placeholder: 'user_... (will become admin)',
condition: { field: 'operation', value: 'clerk_create_organization' },
required: { field: 'operation', value: 'clerk_create_organization' },
},
{
id: 'slug',
title: 'Slug',
type: 'short-input',
placeholder: 'acme-corp',
condition: { field: 'operation', value: 'clerk_create_organization' },
},
{
id: 'maxAllowedMemberships',
title: 'Max Members',
type: 'short-input',
placeholder: '0 for unlimited',
condition: { field: 'operation', value: 'clerk_create_organization' },
},
// Session params
{
id: 'sessionUserId',
title: 'User ID',
type: 'short-input',
placeholder: 'user_...',
condition: { field: 'operation', value: 'clerk_list_sessions' },
},
{
id: 'clientId',
title: 'Client ID',
type: 'short-input',
placeholder: 'client_...',
condition: { field: 'operation', value: 'clerk_list_sessions' },
},
{
id: 'sessionStatus',
title: 'Status',
type: 'dropdown',
options: [
{ label: 'All', id: '' },
{ label: 'Active', id: 'active' },
{ label: 'Ended', id: 'ended' },
{ label: 'Expired', id: 'expired' },
{ label: 'Revoked', id: 'revoked' },
{ label: 'Abandoned', id: 'abandoned' },
{ label: 'Pending', id: 'pending' },
],
value: () => '',
condition: { field: 'operation', value: 'clerk_list_sessions' },
},
{
id: 'sessionId',
title: 'Session ID',
type: 'short-input',
placeholder: 'sess_...',
condition: { field: 'operation', value: ['clerk_get_session', 'clerk_revoke_session'] },
required: { field: 'operation', value: ['clerk_get_session', 'clerk_revoke_session'] },
},
// Pagination params (common)
{
id: 'limit',
title: 'Limit',
type: 'short-input',
placeholder: 'Results per page (1-500, default: 10)',
condition: {
field: 'operation',
value: ['clerk_list_users', 'clerk_list_organizations', 'clerk_list_sessions'],
},
},
{
id: 'offset',
title: 'Offset',
type: 'short-input',
placeholder: 'Skip N results for pagination',
condition: {
field: 'operation',
value: ['clerk_list_users', 'clerk_list_organizations', 'clerk_list_sessions'],
},
},
],
tools: {
access: [
'clerk_list_users',
'clerk_get_user',
'clerk_create_user',
'clerk_update_user',
'clerk_delete_user',
'clerk_list_organizations',
'clerk_get_organization',
'clerk_create_organization',
'clerk_list_sessions',
'clerk_get_session',
'clerk_revoke_session',
],
config: {
tool: (params) => params.operation as string,
params: (params) => {
const {
operation,
secretKey,
emailAddressFilter,
usernameFilter,
orgQuery,
orgName,
sessionUserId,
sessionStatus,
publicMetadata,
privateMetadata,
maxAllowedMemberships,
...rest
} = params
const cleanParams: Record<string, unknown> = {
secretKey,
}
// Map UI fields to API params based on operation
switch (operation) {
case 'clerk_list_users':
if (emailAddressFilter) cleanParams.emailAddress = emailAddressFilter
if (usernameFilter) cleanParams.username = usernameFilter
break
case 'clerk_create_user':
case 'clerk_update_user':
if (publicMetadata) {
cleanParams.publicMetadata =
typeof publicMetadata === 'string' ? JSON.parse(publicMetadata) : publicMetadata
}
if (privateMetadata) {
cleanParams.privateMetadata =
typeof privateMetadata === 'string' ? JSON.parse(privateMetadata) : privateMetadata
}
break
case 'clerk_list_organizations':
if (orgQuery) cleanParams.query = orgQuery
break
case 'clerk_create_organization':
if (orgName) cleanParams.name = orgName
if (maxAllowedMemberships)
cleanParams.maxAllowedMemberships = Number(maxAllowedMemberships)
break
case 'clerk_list_sessions':
if (sessionUserId) cleanParams.userId = sessionUserId
if (sessionStatus) cleanParams.status = sessionStatus
break
}
// Add remaining params that don't need mapping
Object.entries(rest).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== '') {
cleanParams[key] = value
}
})
return cleanParams
},
},
},
inputs: {
operation: { type: 'string', description: 'Operation to perform' },
secretKey: { type: 'string', description: 'Clerk Secret Key' },
userId: { type: 'string', description: 'User ID' },
organizationId: { type: 'string', description: 'Organization ID or slug' },
sessionId: { type: 'string', description: 'Session ID' },
query: { type: 'string', description: 'Search query' },
limit: { type: 'number', description: 'Results per page' },
offset: { type: 'number', description: 'Pagination offset' },
},
outputs: {
// List outputs (arrays stored as json for block compatibility)
users: { type: 'json', description: 'Array of user objects' },
organizations: { type: 'json', description: 'Array of organization objects' },
sessions: { type: 'json', description: 'Array of session objects' },
// Single entity fields (destructured from get/create/update operations)
id: { type: 'string', description: 'Resource ID (user, organization, or session)' },
name: { type: 'string', description: 'Organization name' },
slug: { type: 'string', description: 'Organization slug' },
username: { type: 'string', description: 'Username' },
firstName: { type: 'string', description: 'First name' },
lastName: { type: 'string', description: 'Last name' },
imageUrl: { type: 'string', description: 'Profile image URL' },
hasImage: { type: 'boolean', description: 'Whether resource has an image' },
emailAddresses: { type: 'json', description: 'User email addresses' },
phoneNumbers: { type: 'json', description: 'User phone numbers' },
primaryEmailAddressId: { type: 'string', description: 'Primary email address ID' },
primaryPhoneNumberId: { type: 'string', description: 'Primary phone number ID' },
externalId: { type: 'string', description: 'External system ID' },
passwordEnabled: { type: 'boolean', description: 'Whether password is enabled' },
twoFactorEnabled: { type: 'boolean', description: 'Whether 2FA is enabled' },
banned: { type: 'boolean', description: 'Whether user is banned' },
locked: { type: 'boolean', description: 'Whether user is locked' },
userId: { type: 'string', description: 'User ID (for sessions)' },
clientId: { type: 'string', description: 'Client ID (for sessions)' },
status: { type: 'string', description: 'Session status' },
lastActiveAt: { type: 'number', description: 'Last activity timestamp' },
lastSignInAt: { type: 'number', description: 'Last sign-in timestamp' },
membersCount: { type: 'number', description: 'Number of members' },
maxAllowedMemberships: { type: 'number', description: 'Max allowed memberships' },
adminDeleteEnabled: { type: 'boolean', description: 'Whether admin delete is enabled' },
createdBy: { type: 'string', description: 'Creator user ID' },
publicMetadata: { type: 'json', description: 'Public metadata' },
// Common outputs
totalCount: { type: 'number', description: 'Total count for paginated results' },
deleted: { type: 'boolean', description: 'Whether the resource was deleted' },
object: { type: 'string', description: 'Object type' },
createdAt: { type: 'number', description: 'Creation timestamp' },
updatedAt: { type: 'number', description: 'Last update timestamp' },
success: { type: 'boolean', description: 'Operation success status' },
},
}

View File

@@ -162,5 +162,21 @@ export const HumanInTheLoopBlock: BlockConfig<ResponseBlockOutput> = {
type: 'string', type: 'string',
description: 'Resume API endpoint URL for direct curl requests', description: 'Resume API endpoint URL for direct curl requests',
}, },
response: {
type: 'json',
description: 'Display data shown to the approver',
hiddenFromDisplay: true,
},
submission: {
type: 'json',
description: 'Form submission data from the approver',
hiddenFromDisplay: true,
},
resumeInput: {
type: 'json',
description: 'Raw input data submitted when resuming',
hiddenFromDisplay: true,
},
submittedAt: { type: 'string', description: 'ISO timestamp when the workflow was resumed' },
}, },
} }

View File

@@ -247,6 +247,7 @@ export const RouterBlock: BlockConfig<RouterResponse> = {
tokens: { type: 'json', description: 'Token usage' }, tokens: { type: 'json', description: 'Token usage' },
cost: { type: 'json', description: 'Cost information' }, cost: { type: 'json', description: 'Cost information' },
selectedPath: { type: 'json', description: 'Selected routing path' }, selectedPath: { type: 'json', description: 'Selected routing path' },
selectedRoute: { type: 'string', description: 'Selected route ID' },
}, },
} }

View File

@@ -44,6 +44,11 @@ export const WorkflowBlock: BlockConfig = {
childWorkflowName: { type: 'string', description: 'Child workflow name' }, childWorkflowName: { type: 'string', description: 'Child workflow name' },
result: { type: 'json', description: 'Workflow execution result' }, result: { type: 'json', description: 'Workflow execution result' },
error: { type: 'string', description: 'Error message' }, error: { type: 'string', description: 'Error message' },
childTraceSpans: {
type: 'json',
description: 'Child workflow trace spans',
hiddenFromDisplay: true,
},
}, },
hideFromToolbar: true, hideFromToolbar: true,
} }

View File

@@ -43,5 +43,10 @@ export const WorkflowInputBlock: BlockConfig = {
childWorkflowName: { type: 'string', description: 'Child workflow name' }, childWorkflowName: { type: 'string', description: 'Child workflow name' },
result: { type: 'json', description: 'Workflow execution result' }, result: { type: 'json', description: 'Workflow execution result' },
error: { type: 'string', description: 'Error message' }, error: { type: 'string', description: 'Error message' },
childTraceSpans: {
type: 'json',
description: 'Child workflow trace spans',
hiddenFromDisplay: true,
},
}, },
} }

View File

@@ -13,6 +13,7 @@ import { CalendlyBlock } from '@/blocks/blocks/calendly'
import { ChatTriggerBlock } from '@/blocks/blocks/chat_trigger' import { ChatTriggerBlock } from '@/blocks/blocks/chat_trigger'
import { CirclebackBlock } from '@/blocks/blocks/circleback' import { CirclebackBlock } from '@/blocks/blocks/circleback'
import { ClayBlock } from '@/blocks/blocks/clay' import { ClayBlock } from '@/blocks/blocks/clay'
import { ClerkBlock } from '@/blocks/blocks/clerk'
import { ConditionBlock } from '@/blocks/blocks/condition' import { ConditionBlock } from '@/blocks/blocks/condition'
import { ConfluenceBlock, ConfluenceV2Block } from '@/blocks/blocks/confluence' import { ConfluenceBlock, ConfluenceV2Block } from '@/blocks/blocks/confluence'
import { CursorBlock, CursorV2Block } from '@/blocks/blocks/cursor' import { CursorBlock, CursorV2Block } from '@/blocks/blocks/cursor'
@@ -168,6 +169,7 @@ export const registry: Record<string, BlockConfig> = {
chat_trigger: ChatTriggerBlock, chat_trigger: ChatTriggerBlock,
circleback: CirclebackBlock, circleback: CirclebackBlock,
clay: ClayBlock, clay: ClayBlock,
clerk: ClerkBlock,
condition: ConditionBlock, condition: ConditionBlock,
confluence: ConfluenceBlock, confluence: ConfluenceBlock,
confluence_v2: ConfluenceV2Block, confluence_v2: ConfluenceV2Block,

View File

@@ -157,8 +157,19 @@ export type OutputFieldDefinition =
* Uses the same condition format as subBlocks. * Uses the same condition format as subBlocks.
*/ */
condition?: OutputCondition condition?: OutputCondition
/**
* If true, this output is hidden from display in the tag dropdown and logs,
* but still available for resolution and execution.
*/
hiddenFromDisplay?: boolean
} }
export function isHiddenFromDisplay(def: unknown): boolean {
return Boolean(
def && typeof def === 'object' && 'hiddenFromDisplay' in def && def.hiddenFromDisplay
)
}
export interface ParamConfig { export interface ParamConfig {
type: ParamType type: ParamType
description?: string description?: string

View File

@@ -2096,6 +2096,23 @@ export function ClayIcon(props: SVGProps<SVGSVGElement>) {
) )
} }
export function ClerkIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} viewBox='0 0 128 128' fill='none' xmlns='http://www.w3.org/2000/svg'>
<circle cx='64' cy='64' r='20' fill='white' />
<path
d='M99.5716 10.788C101.571 12.1272 101.742 14.9444 100.04 16.646L85.4244 31.2618C84.1035 32.5828 82.0542 32.7914 80.3915 31.9397C75.4752 29.421 69.9035 28 64 28C44.1177 28 28 44.1177 28 64C28 69.9035 29.421 75.4752 31.9397 80.3915C32.7914 82.0542 32.5828 84.1035 31.2618 85.4244L16.646 100.04C14.9444 101.742 12.1272 101.571 10.788 99.5716C3.97411 89.3989 0 77.1635 0 64C0 28.6538 28.6538 0 64 0C77.1635 0 89.3989 3.97411 99.5716 10.788Z'
fill='white'
fillOpacity='0.4'
/>
<path
d='M100.04 111.354C101.742 113.056 101.571 115.873 99.5717 117.212C89.3989 124.026 77.1636 128 64 128C50.8364 128 38.6011 124.026 28.4283 117.212C26.4289 115.873 26.2581 113.056 27.9597 111.354L42.5755 96.7382C43.8965 95.4172 45.9457 95.2085 47.6084 96.0603C52.5248 98.579 58.0964 100 64 100C69.9036 100 75.4753 98.579 80.3916 96.0603C82.0543 95.2085 84.1036 95.4172 85.4245 96.7382L100.04 111.354Z'
fill='white'
/>
</svg>
)
}
export function MicrosoftIcon(props: SVGProps<SVGSVGElement>) { export function MicrosoftIcon(props: SVGProps<SVGSVGElement>) {
return ( return (
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 23 23' {...props}> <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 23 23' {...props}>

View File

@@ -1,5 +1,16 @@
import type { LoopType, ParallelType } from '@/lib/workflows/types' import type { LoopType, ParallelType } from '@/lib/workflows/types'
/**
* Runtime-injected keys for trigger blocks that should be hidden from logs/display.
* These are added during execution but aren't part of the block's static output schema.
*/
export const TRIGGER_INTERNAL_KEYS = ['webhook', 'workflowId'] as const
export type TriggerInternalKey = (typeof TRIGGER_INTERNAL_KEYS)[number]
export function isTriggerInternalKey(key: string): key is TriggerInternalKey {
return TRIGGER_INTERNAL_KEYS.includes(key as TriggerInternalKey)
}
export enum BlockType { export enum BlockType {
PARALLEL = 'parallel', PARALLEL = 'parallel',
LOOP = 'loop', LOOP = 'loop',

View File

@@ -11,8 +11,6 @@ import {
DEFAULTS, DEFAULTS,
EDGE, EDGE,
isSentinelBlockType, isSentinelBlockType,
isTriggerBehavior,
isWorkflowBlockType,
} from '@/executor/constants' } from '@/executor/constants'
import type { DAGNode } from '@/executor/dag/builder' import type { DAGNode } from '@/executor/dag/builder'
import { ChildWorkflowError } from '@/executor/errors/child-workflow-error' import { ChildWorkflowError } from '@/executor/errors/child-workflow-error'
@@ -30,6 +28,8 @@ import type {
} from '@/executor/types' } from '@/executor/types'
import { streamingResponseFormatProcessor } from '@/executor/utils' import { streamingResponseFormatProcessor } from '@/executor/utils'
import { buildBlockExecutionError, normalizeError } from '@/executor/utils/errors' import { buildBlockExecutionError, normalizeError } from '@/executor/utils/errors'
import { isJSONString } from '@/executor/utils/json'
import { filterOutputForLog } from '@/executor/utils/output-filter'
import { validateBlockType } from '@/executor/utils/permission-check' import { validateBlockType } from '@/executor/utils/permission-check'
import type { VariableResolver } from '@/executor/variables/resolver' import type { VariableResolver } from '@/executor/variables/resolver'
import type { SerializedBlock } from '@/serializer/types' import type { SerializedBlock } from '@/serializer/types'
@@ -87,7 +87,7 @@ export class BlockExecutor {
resolvedInputs = this.resolver.resolveInputs(ctx, node.id, block.config.params, block) resolvedInputs = this.resolver.resolveInputs(ctx, node.id, block.config.params, block)
if (blockLog) { if (blockLog) {
blockLog.input = resolvedInputs blockLog.input = this.parseJsonInputs(resolvedInputs)
} }
} catch (error) { } catch (error) {
cleanupSelfReference?.() cleanupSelfReference?.()
@@ -149,14 +149,23 @@ export class BlockExecutor {
blockLog.endedAt = new Date().toISOString() blockLog.endedAt = new Date().toISOString()
blockLog.durationMs = duration blockLog.durationMs = duration
blockLog.success = true blockLog.success = true
blockLog.output = this.filterOutputForLog(block, normalizedOutput) blockLog.output = filterOutputForLog(block.metadata?.id || '', normalizedOutput, { block })
} }
this.state.setBlockOutput(node.id, normalizedOutput, duration) this.state.setBlockOutput(node.id, normalizedOutput, duration)
if (!isSentinel) { if (!isSentinel) {
const displayOutput = this.filterOutputForDisplay(block, normalizedOutput) const displayOutput = filterOutputForLog(block.metadata?.id || '', normalizedOutput, {
this.callOnBlockComplete(ctx, node, block, resolvedInputs, displayOutput, duration) block,
})
this.callOnBlockComplete(
ctx,
node,
block,
this.parseJsonInputs(resolvedInputs),
displayOutput,
duration
)
} }
return normalizedOutput return normalizedOutput
@@ -232,8 +241,8 @@ export class BlockExecutor {
blockLog.durationMs = duration blockLog.durationMs = duration
blockLog.success = false blockLog.success = false
blockLog.error = errorMessage blockLog.error = errorMessage
blockLog.input = input blockLog.input = this.parseJsonInputs(input)
blockLog.output = this.filterOutputForLog(block, errorOutput) blockLog.output = filterOutputForLog(block.metadata?.id || '', errorOutput, { block })
} }
logger.error( logger.error(
@@ -246,8 +255,15 @@ export class BlockExecutor {
) )
if (!isSentinel) { if (!isSentinel) {
const displayOutput = this.filterOutputForDisplay(block, errorOutput) const displayOutput = filterOutputForLog(block.metadata?.id || '', errorOutput, { block })
this.callOnBlockComplete(ctx, node, block, input, displayOutput, duration) this.callOnBlockComplete(
ctx,
node,
block,
this.parseJsonInputs(input),
displayOutput,
duration
)
} }
const hasErrorPort = this.hasErrorPortEdge(node) const hasErrorPort = this.hasErrorPortEdge(node)
@@ -335,49 +351,34 @@ export class BlockExecutor {
return { result: output } return { result: output }
} }
private filterOutputForLog( /**
block: SerializedBlock, * Parse JSON string inputs to objects for log display only.
output: NormalizedBlockOutput * Attempts to parse any string that looks like JSON.
): NormalizedBlockOutput { * Returns a new object - does not mutate the original inputs.
const blockType = block.metadata?.id */
private parseJsonInputs(inputs: Record<string, any>): Record<string, any> {
let result = inputs
let hasChanges = false
if (blockType === BlockType.HUMAN_IN_THE_LOOP) { for (const [key, value] of Object.entries(inputs)) {
const filtered: NormalizedBlockOutput = {} // isJSONString is a quick heuristic (checks for { or [), not a validator.
for (const [key, value] of Object.entries(output)) { // Invalid JSON is safely caught below - this just avoids JSON.parse on every string.
if (key.startsWith('_')) continue if (typeof value !== 'string' || !isJSONString(value)) {
if (key === 'response') continue continue
filtered[key] = value
} }
return filtered
}
if (isTriggerBehavior(block)) { try {
const filtered: NormalizedBlockOutput = {} if (!hasChanges) {
const internalKeys = ['webhook', 'workflowId'] result = { ...inputs }
for (const [key, value] of Object.entries(output)) { hasChanges = true
if (internalKeys.includes(key)) continue }
filtered[key] = value result[key] = JSON.parse(value.trim())
} catch {
// Not valid JSON, keep original string
} }
return filtered
} }
return output return result
}
private filterOutputForDisplay(
block: SerializedBlock,
output: NormalizedBlockOutput
): NormalizedBlockOutput {
const filtered = this.filterOutputForLog(block, output)
if (isWorkflowBlockType(block.metadata?.id)) {
const { childTraceSpans: _, ...displayOutput } = filtered as {
childTraceSpans?: unknown
} & Record<string, unknown>
return displayOutput
}
return filtered
} }
private callOnBlockStart(ctx: ExecutionContext, node: DAGNode, block: SerializedBlock): void { private callOnBlockStart(ctx: ExecutionContext, node: DAGNode, block: SerializedBlock): void {

View File

@@ -936,8 +936,12 @@ export class AgentBlockHandler implements BlockHandler {
systemPrompt: validMessages ? undefined : inputs.systemPrompt, systemPrompt: validMessages ? undefined : inputs.systemPrompt,
context: validMessages ? undefined : stringifyJSON(messages), context: validMessages ? undefined : stringifyJSON(messages),
tools: formattedTools, tools: formattedTools,
temperature: inputs.temperature, temperature:
maxTokens: inputs.maxTokens, inputs.temperature != null && inputs.temperature !== ''
? Number(inputs.temperature)
: undefined,
maxTokens:
inputs.maxTokens != null && inputs.maxTokens !== '' ? Number(inputs.maxTokens) : undefined,
apiKey: inputs.apiKey, apiKey: inputs.apiKey,
azureEndpoint: inputs.azureEndpoint, azureEndpoint: inputs.azureEndpoint,
azureApiVersion: inputs.azureApiVersion, azureApiVersion: inputs.azureApiVersion,

View File

@@ -14,8 +14,8 @@ export interface AgentInputs {
slidingWindowSize?: string // For message-based sliding window slidingWindowSize?: string // For message-based sliding window
slidingWindowTokens?: string // For token-based sliding window slidingWindowTokens?: string // For token-based sliding window
// LLM parameters // LLM parameters
temperature?: number temperature?: string
maxTokens?: number maxTokens?: string
apiKey?: string apiKey?: string
azureEndpoint?: string azureEndpoint?: string
azureApiVersion?: string azureApiVersion?: string

View File

@@ -1,5 +1,5 @@
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { BlockType, isTriggerBehavior } from '@/executor/constants' import { BlockType, isTriggerBehavior, isTriggerInternalKey } from '@/executor/constants'
import type { BlockHandler, ExecutionContext } from '@/executor/types' import type { BlockHandler, ExecutionContext } from '@/executor/types'
import type { SerializedBlock } from '@/serializer/types' import type { SerializedBlock } from '@/serializer/types'
@@ -33,7 +33,12 @@ export class TriggerBlockHandler implements BlockHandler {
const starterOutput = starterState.output const starterOutput = starterState.output
if (starterOutput.webhook?.data) { if (starterOutput.webhook?.data) {
const { webhook, workflowId, ...cleanOutput } = starterOutput const cleanOutput: Record<string, unknown> = {}
for (const [key, value] of Object.entries(starterOutput)) {
if (!isTriggerInternalKey(key)) {
cleanOutput[key] = value
}
}
return cleanOutput return cleanOutput
} }

View File

@@ -0,0 +1,51 @@
import { getBlock } from '@/blocks'
import { isHiddenFromDisplay } from '@/blocks/types'
import { isTriggerBehavior, isTriggerInternalKey } from '@/executor/constants'
import type { NormalizedBlockOutput } from '@/executor/types'
import type { SerializedBlock } from '@/serializer/types'
/**
* Filters block output for logging/display purposes.
* Removes internal fields and fields marked with hiddenFromDisplay.
*
* @param blockType - The block type string (e.g., 'human_in_the_loop', 'workflow')
* @param output - The raw block output to filter
* @param options - Optional configuration
* @param options.block - Full SerializedBlock for trigger behavior detection
* @param options.additionalHiddenKeys - Extra keys to filter out (e.g., 'resume')
*/
export function filterOutputForLog(
blockType: string,
output: NormalizedBlockOutput,
options?: {
block?: SerializedBlock
additionalHiddenKeys?: string[]
}
): NormalizedBlockOutput {
const blockConfig = blockType ? getBlock(blockType) : undefined
const filtered: NormalizedBlockOutput = {}
const additionalHiddenKeys = options?.additionalHiddenKeys ?? []
for (const [key, value] of Object.entries(output)) {
// Skip internal keys (underscore prefix)
if (key.startsWith('_')) continue
if (blockConfig?.outputs && isHiddenFromDisplay(blockConfig.outputs[key])) {
continue
}
// Skip runtime-injected trigger keys not in block config
if (options?.block && isTriggerBehavior(options.block) && isTriggerInternalKey(key)) {
continue
}
// Skip additional hidden keys specified by caller
if (additionalHiddenKeys.includes(key)) {
continue
}
filtered[key] = value
}
return filtered
}

View File

@@ -4,6 +4,7 @@ import { createLogger } from '@sim/logger'
import { and, eq, isNull } from 'drizzle-orm' import { and, eq, isNull } from 'drizzle-orm'
import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/persistence/utils' import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/persistence/utils'
import { sanitizeForCopilot } from '@/lib/workflows/sanitization/json-sanitizer' import { sanitizeForCopilot } from '@/lib/workflows/sanitization/json-sanitizer'
import { isHiddenFromDisplay } from '@/blocks/types'
import { escapeRegExp } from '@/executor/constants' import { escapeRegExp } from '@/executor/constants'
import { getUserPermissionConfig } from '@/executor/utils/permission-check' import { getUserPermissionConfig } from '@/executor/utils/permission-check'
import type { ChatContext } from '@/stores/panel/copilot/types' import type { ChatContext } from '@/stores/panel/copilot/types'
@@ -397,7 +398,11 @@ async function processBlockMetadata(
category: blockConfig.category, category: blockConfig.category,
bgColor: blockConfig.bgColor, bgColor: blockConfig.bgColor,
inputs: blockConfig.inputs || {}, inputs: blockConfig.inputs || {},
outputs: blockConfig.outputs || {}, outputs: blockConfig.outputs
? Object.fromEntries(
Object.entries(blockConfig.outputs).filter(([_, def]) => !isHiddenFromDisplay(def))
)
: {},
tools: blockConfig.tools?.access || [], tools: blockConfig.tools?.access || [],
hideFromToolbar: blockConfig.hideFromToolbar, hideFromToolbar: blockConfig.hideFromToolbar,
} }

View File

@@ -6,7 +6,7 @@ import {
type GetBlockConfigResultType, type GetBlockConfigResultType,
} from '@/lib/copilot/tools/shared/schemas' } from '@/lib/copilot/tools/shared/schemas'
import { registry as blockRegistry, getLatestBlock } from '@/blocks/registry' import { registry as blockRegistry, getLatestBlock } from '@/blocks/registry'
import type { SubBlockConfig } from '@/blocks/types' import { isHiddenFromDisplay, type SubBlockConfig } from '@/blocks/types'
import { getUserPermissionConfig } from '@/executor/utils/permission-check' import { getUserPermissionConfig } from '@/executor/utils/permission-check'
import { PROVIDER_DEFINITIONS } from '@/providers/models' import { PROVIDER_DEFINITIONS } from '@/providers/models'
import { tools as toolsRegistry } from '@/tools/registry' import { tools as toolsRegistry } from '@/tools/registry'
@@ -310,6 +310,7 @@ function extractTriggerOutputs(blockConfig: any): Record<string, OutputFieldSche
const trigger = getTrigger(triggerId) const trigger = getTrigger(triggerId)
if (trigger.outputs) { if (trigger.outputs) {
for (const [key, def] of Object.entries(trigger.outputs)) { for (const [key, def] of Object.entries(trigger.outputs)) {
if (isHiddenFromDisplay(def)) continue
outputs[key] = extractOutputField(def) outputs[key] = extractOutputField(def)
} }
} }
@@ -342,6 +343,7 @@ function extractOutputs(
const tool = toolsRegistry[toolId] const tool = toolsRegistry[toolId]
if (tool?.outputs) { if (tool?.outputs) {
for (const [key, def] of Object.entries(tool.outputs)) { for (const [key, def] of Object.entries(tool.outputs)) {
if (isHiddenFromDisplay(def)) continue
outputs[key] = extractOutputField(def) outputs[key] = extractOutputField(def)
} }
return outputs return outputs
@@ -355,6 +357,7 @@ function extractOutputs(
// Use block-level outputs // Use block-level outputs
if (blockConfig.outputs) { if (blockConfig.outputs) {
for (const [key, def] of Object.entries(blockConfig.outputs)) { for (const [key, def] of Object.entries(blockConfig.outputs)) {
if (isHiddenFromDisplay(def)) continue
outputs[key] = extractOutputField(def) outputs[key] = extractOutputField(def)
} }
} }

View File

@@ -7,8 +7,7 @@ import {
GetBlocksMetadataResult, GetBlocksMetadataResult,
} from '@/lib/copilot/tools/shared/schemas' } from '@/lib/copilot/tools/shared/schemas'
import { registry as blockRegistry } from '@/blocks/registry' import { registry as blockRegistry } from '@/blocks/registry'
import type { BlockConfig } from '@/blocks/types' import { AuthMode, type BlockConfig, isHiddenFromDisplay } from '@/blocks/types'
import { AuthMode } from '@/blocks/types'
import { getUserPermissionConfig } from '@/executor/utils/permission-check' import { getUserPermissionConfig } from '@/executor/utils/permission-check'
import { PROVIDER_DEFINITIONS } from '@/providers/models' import { PROVIDER_DEFINITIONS } from '@/providers/models'
import { tools as toolsRegistry } from '@/tools/registry' import { tools as toolsRegistry } from '@/tools/registry'
@@ -249,6 +248,12 @@ export const getBlocksMetadataServerTool: BaseServerTool<
} }
} }
const filteredOutputs = blockConfig.outputs
? Object.fromEntries(
Object.entries(blockConfig.outputs).filter(([_, def]) => !isHiddenFromDisplay(def))
)
: undefined
metadata = { metadata = {
id: blockId, id: blockId,
name: blockConfig.name || blockId, name: blockConfig.name || blockId,
@@ -262,7 +267,7 @@ export const getBlocksMetadataServerTool: BaseServerTool<
triggers, triggers,
operationInputSchema: operationParameters, operationInputSchema: operationParameters,
operations, operations,
outputs: blockConfig.outputs, outputs: filteredOutputs,
} }
} }

View File

@@ -8,7 +8,7 @@ const ivm = require('isolated-vm')
const USER_CODE_START_LINE = 4 const USER_CODE_START_LINE = 4
const pendingFetches = new Map() const pendingFetches = new Map()
let fetchIdCounter = 0 let fetchIdCounter = 0
const FETCH_TIMEOUT_MS = 30000 const FETCH_TIMEOUT_MS = 300000 // 5 minutes
/** /**
* Extract line and column from error stack or message * Extract line and column from error stack or message

View File

@@ -34,6 +34,7 @@ export function layoutContainers(
: DEFAULT_CONTAINER_HORIZONTAL_SPACING, : DEFAULT_CONTAINER_HORIZONTAL_SPACING,
verticalSpacing: options.verticalSpacing ?? DEFAULT_VERTICAL_SPACING, verticalSpacing: options.verticalSpacing ?? DEFAULT_VERTICAL_SPACING,
padding: { x: CONTAINER_PADDING_X, y: CONTAINER_PADDING_Y }, padding: { x: CONTAINER_PADDING_X, y: CONTAINER_PADDING_Y },
gridSize: options.gridSize,
} }
for (const [parentId, childIds] of children.entries()) { for (const [parentId, childIds] of children.entries()) {
@@ -56,18 +57,15 @@ export function layoutContainers(
continue continue
} }
// Use the shared core layout function with container options
const { nodes, dimensions } = layoutBlocksCore(childBlocks, childEdges, { const { nodes, dimensions } = layoutBlocksCore(childBlocks, childEdges, {
isContainer: true, isContainer: true,
layoutOptions: containerOptions, layoutOptions: containerOptions,
}) })
// Apply positions back to blocks
for (const node of nodes.values()) { for (const node of nodes.values()) {
blocks[node.id].position = node.position blocks[node.id].position = node.position
} }
// Update container dimensions
const calculatedWidth = dimensions.width const calculatedWidth = dimensions.width
const calculatedHeight = dimensions.height const calculatedHeight = dimensions.height

View File

@@ -9,6 +9,7 @@ import {
getBlockMetrics, getBlockMetrics,
normalizePositions, normalizePositions,
prepareBlockMetrics, prepareBlockMetrics,
snapNodesToGrid,
} from '@/lib/workflows/autolayout/utils' } from '@/lib/workflows/autolayout/utils'
import { BLOCK_DIMENSIONS, HANDLE_POSITIONS } from '@/lib/workflows/blocks/block-dimensions' import { BLOCK_DIMENSIONS, HANDLE_POSITIONS } from '@/lib/workflows/blocks/block-dimensions'
import { EDGE } from '@/executor/constants' import { EDGE } from '@/executor/constants'
@@ -84,7 +85,6 @@ export function assignLayers(
): Map<string, GraphNode> { ): Map<string, GraphNode> {
const nodes = new Map<string, GraphNode>() const nodes = new Map<string, GraphNode>()
// Initialize nodes
for (const [id, block] of Object.entries(blocks)) { for (const [id, block] of Object.entries(blocks)) {
nodes.set(id, { nodes.set(id, {
id, id,
@@ -97,7 +97,6 @@ export function assignLayers(
}) })
} }
// Build a map of target node -> edges coming into it (to check sourceHandle later)
const incomingEdgesMap = new Map<string, Edge[]>() const incomingEdgesMap = new Map<string, Edge[]>()
for (const edge of edges) { for (const edge of edges) {
if (!incomingEdgesMap.has(edge.target)) { if (!incomingEdgesMap.has(edge.target)) {
@@ -106,7 +105,6 @@ export function assignLayers(
incomingEdgesMap.get(edge.target)!.push(edge) incomingEdgesMap.get(edge.target)!.push(edge)
} }
// Build adjacency from edges
for (const edge of edges) { for (const edge of edges) {
const sourceNode = nodes.get(edge.source) const sourceNode = nodes.get(edge.source)
const targetNode = nodes.get(edge.target) const targetNode = nodes.get(edge.target)
@@ -117,7 +115,6 @@ export function assignLayers(
} }
} }
// Find starter nodes (no incoming edges)
const starterNodes = Array.from(nodes.values()).filter((node) => node.incoming.size === 0) const starterNodes = Array.from(nodes.values()).filter((node) => node.incoming.size === 0)
if (starterNodes.length === 0 && nodes.size > 0) { if (starterNodes.length === 0 && nodes.size > 0) {
@@ -126,7 +123,6 @@ export function assignLayers(
logger.warn('No starter blocks found, using first block as starter', { blockId: firstNode.id }) logger.warn('No starter blocks found, using first block as starter', { blockId: firstNode.id })
} }
// Topological sort using Kahn's algorithm
const inDegreeCount = new Map<string, number>() const inDegreeCount = new Map<string, number>()
for (const node of nodes.values()) { for (const node of nodes.values()) {
@@ -144,8 +140,6 @@ export function assignLayers(
const node = nodes.get(nodeId)! const node = nodes.get(nodeId)!
processed.add(nodeId) processed.add(nodeId)
// Calculate layer based on max incoming layer + 1
// For edges from subflow ends, add the subflow's internal depth (minus 1 to avoid double-counting)
if (node.incoming.size > 0) { if (node.incoming.size > 0) {
let maxEffectiveLayer = -1 let maxEffectiveLayer = -1
const incomingEdges = incomingEdgesMap.get(nodeId) || [] const incomingEdges = incomingEdgesMap.get(nodeId) || []
@@ -153,16 +147,11 @@ export function assignLayers(
for (const incomingId of node.incoming) { for (const incomingId of node.incoming) {
const incomingNode = nodes.get(incomingId) const incomingNode = nodes.get(incomingId)
if (incomingNode) { if (incomingNode) {
// Find edges from this incoming node to check if it's a subflow end edge
const edgesFromSource = incomingEdges.filter((e) => e.source === incomingId) const edgesFromSource = incomingEdges.filter((e) => e.source === incomingId)
let additionalDepth = 0 let additionalDepth = 0
// Check if any edge from this source is a subflow end edge
const hasSubflowEndEdge = edgesFromSource.some(isSubflowEndEdge) const hasSubflowEndEdge = edgesFromSource.some(isSubflowEndEdge)
if (hasSubflowEndEdge && subflowDepths) { if (hasSubflowEndEdge && subflowDepths) {
// Get the internal depth of the subflow
// Subtract 1 because the +1 at the end of layer calculation already accounts for one layer
// E.g., if subflow has 2 internal layers (depth=2), we add 1 extra so total offset is 2
const depth = subflowDepths.get(incomingId) ?? 1 const depth = subflowDepths.get(incomingId) ?? 1
additionalDepth = Math.max(0, depth - 1) additionalDepth = Math.max(0, depth - 1)
} }
@@ -174,7 +163,6 @@ export function assignLayers(
node.layer = maxEffectiveLayer + 1 node.layer = maxEffectiveLayer + 1
} }
// Add outgoing nodes when all dependencies processed
for (const targetId of node.outgoing) { for (const targetId of node.outgoing) {
const currentCount = inDegreeCount.get(targetId) || 0 const currentCount = inDegreeCount.get(targetId) || 0
inDegreeCount.set(targetId, currentCount - 1) inDegreeCount.set(targetId, currentCount - 1)
@@ -185,7 +173,6 @@ export function assignLayers(
} }
} }
// Handle isolated nodes
for (const node of nodes.values()) { for (const node of nodes.values()) {
if (!processed.has(node.id)) { if (!processed.has(node.id)) {
logger.debug('Isolated node detected, assigning to layer 0', { blockId: node.id }) logger.debug('Isolated node detected, assigning to layer 0', { blockId: node.id })
@@ -224,7 +211,6 @@ function resolveVerticalOverlaps(nodes: GraphNode[], verticalSpacing: number): v
hasOverlap = false hasOverlap = false
iteration++ iteration++
// Group nodes by layer for same-layer overlap resolution
const nodesByLayer = new Map<number, GraphNode[]>() const nodesByLayer = new Map<number, GraphNode[]>()
for (const node of nodes) { for (const node of nodes) {
if (!nodesByLayer.has(node.layer)) { if (!nodesByLayer.has(node.layer)) {
@@ -233,11 +219,9 @@ function resolveVerticalOverlaps(nodes: GraphNode[], verticalSpacing: number): v
nodesByLayer.get(node.layer)!.push(node) nodesByLayer.get(node.layer)!.push(node)
} }
// Process each layer independently
for (const [layer, layerNodes] of nodesByLayer) { for (const [layer, layerNodes] of nodesByLayer) {
if (layerNodes.length < 2) continue if (layerNodes.length < 2) continue
// Sort by Y position for consistent processing
layerNodes.sort((a, b) => a.position.y - b.position.y) layerNodes.sort((a, b) => a.position.y - b.position.y)
for (let i = 0; i < layerNodes.length - 1; i++) { for (let i = 0; i < layerNodes.length - 1; i++) {
@@ -302,7 +286,6 @@ export function calculatePositions(
const layerNumbers = Array.from(layers.keys()).sort((a, b) => a - b) const layerNumbers = Array.from(layers.keys()).sort((a, b) => a - b)
// Calculate max width for each layer
const layerWidths = new Map<number, number>() const layerWidths = new Map<number, number>()
for (const layerNum of layerNumbers) { for (const layerNum of layerNumbers) {
const nodesInLayer = layers.get(layerNum)! const nodesInLayer = layers.get(layerNum)!
@@ -310,7 +293,6 @@ export function calculatePositions(
layerWidths.set(layerNum, maxWidth) layerWidths.set(layerNum, maxWidth)
} }
// Calculate cumulative X positions for each layer based on actual widths
const layerXPositions = new Map<number, number>() const layerXPositions = new Map<number, number>()
let cumulativeX = padding.x let cumulativeX = padding.x
@@ -319,7 +301,6 @@ export function calculatePositions(
cumulativeX += layerWidths.get(layerNum)! + horizontalSpacing cumulativeX += layerWidths.get(layerNum)! + horizontalSpacing
} }
// Build a flat map of all nodes for quick lookups
const allNodes = new Map<string, GraphNode>() const allNodes = new Map<string, GraphNode>()
for (const nodesInLayer of layers.values()) { for (const nodesInLayer of layers.values()) {
for (const node of nodesInLayer) { for (const node of nodesInLayer) {
@@ -327,7 +308,6 @@ export function calculatePositions(
} }
} }
// Build incoming edges map for handle lookups
const incomingEdgesMap = new Map<string, Edge[]>() const incomingEdgesMap = new Map<string, Edge[]>()
for (const edge of edges) { for (const edge of edges) {
if (!incomingEdgesMap.has(edge.target)) { if (!incomingEdgesMap.has(edge.target)) {
@@ -336,20 +316,16 @@ export function calculatePositions(
incomingEdgesMap.get(edge.target)!.push(edge) incomingEdgesMap.get(edge.target)!.push(edge)
} }
// Position nodes layer by layer, aligning with connected predecessors
for (const layerNum of layerNumbers) { for (const layerNum of layerNumbers) {
const nodesInLayer = layers.get(layerNum)! const nodesInLayer = layers.get(layerNum)!
const xPosition = layerXPositions.get(layerNum)! const xPosition = layerXPositions.get(layerNum)!
// Separate containers and non-containers
const containersInLayer = nodesInLayer.filter(isContainerBlock) const containersInLayer = nodesInLayer.filter(isContainerBlock)
const nonContainersInLayer = nodesInLayer.filter((n) => !isContainerBlock(n)) const nonContainersInLayer = nodesInLayer.filter((n) => !isContainerBlock(n))
// For the first layer (layer 0), position sequentially from padding.y
if (layerNum === 0) { if (layerNum === 0) {
let yOffset = padding.y let yOffset = padding.y
// Sort containers by height for visual balance
containersInLayer.sort((a, b) => b.metrics.height - a.metrics.height) containersInLayer.sort((a, b) => b.metrics.height - a.metrics.height)
for (const node of containersInLayer) { for (const node of containersInLayer) {
@@ -361,7 +337,6 @@ export function calculatePositions(
yOffset += CONTAINER_VERTICAL_CLEARANCE yOffset += CONTAINER_VERTICAL_CLEARANCE
} }
// Sort non-containers by outgoing connections
nonContainersInLayer.sort((a, b) => b.outgoing.size - a.outgoing.size) nonContainersInLayer.sort((a, b) => b.outgoing.size - a.outgoing.size)
for (const node of nonContainersInLayer) { for (const node of nonContainersInLayer) {
@@ -371,9 +346,7 @@ export function calculatePositions(
continue continue
} }
// For subsequent layers, align with connected predecessors (handle-to-handle)
for (const node of [...containersInLayer, ...nonContainersInLayer]) { for (const node of [...containersInLayer, ...nonContainersInLayer]) {
// Find the bottommost predecessor handle Y (highest value) and align to it
let bestSourceHandleY = -1 let bestSourceHandleY = -1
let bestEdge: Edge | null = null let bestEdge: Edge | null = null
const incomingEdges = incomingEdgesMap.get(node.id) || [] const incomingEdges = incomingEdgesMap.get(node.id) || []
@@ -381,7 +354,6 @@ export function calculatePositions(
for (const edge of incomingEdges) { for (const edge of incomingEdges) {
const predecessor = allNodes.get(edge.source) const predecessor = allNodes.get(edge.source)
if (predecessor) { if (predecessor) {
// Calculate actual source handle Y position based on block type and handle
const sourceHandleOffset = getSourceHandleYOffset(predecessor.block, edge.sourceHandle) const sourceHandleOffset = getSourceHandleYOffset(predecessor.block, edge.sourceHandle)
const sourceHandleY = predecessor.position.y + sourceHandleOffset const sourceHandleY = predecessor.position.y + sourceHandleOffset
@@ -392,20 +364,16 @@ export function calculatePositions(
} }
} }
// If no predecessors found (shouldn't happen for layer > 0), use padding
if (bestSourceHandleY < 0) { if (bestSourceHandleY < 0) {
bestSourceHandleY = padding.y + HANDLE_POSITIONS.DEFAULT_Y_OFFSET bestSourceHandleY = padding.y + HANDLE_POSITIONS.DEFAULT_Y_OFFSET
} }
// Calculate the target handle Y offset for this node
const targetHandleOffset = getTargetHandleYOffset(node.block, bestEdge?.targetHandle) const targetHandleOffset = getTargetHandleYOffset(node.block, bestEdge?.targetHandle)
// Position node so its target handle aligns with the source handle Y
node.position = { x: xPosition, y: bestSourceHandleY - targetHandleOffset } node.position = { x: xPosition, y: bestSourceHandleY - targetHandleOffset }
} }
} }
// Resolve vertical overlaps within layers (X overlaps prevented by cumulative positioning)
resolveVerticalOverlaps(Array.from(layers.values()).flat(), verticalSpacing) resolveVerticalOverlaps(Array.from(layers.values()).flat(), verticalSpacing)
} }
@@ -435,7 +403,7 @@ export function layoutBlocksCore(
return { nodes: new Map(), dimensions: { width: 0, height: 0 } } return { nodes: new Map(), dimensions: { width: 0, height: 0 } }
} }
const layoutOptions = const layoutOptions: LayoutOptions =
options.layoutOptions ?? options.layoutOptions ??
(options.isContainer ? CONTAINER_LAYOUT_OPTIONS : DEFAULT_LAYOUT_OPTIONS) (options.isContainer ? CONTAINER_LAYOUT_OPTIONS : DEFAULT_LAYOUT_OPTIONS)
@@ -452,7 +420,13 @@ export function layoutBlocksCore(
calculatePositions(layers, edges, layoutOptions) calculatePositions(layers, edges, layoutOptions)
// 5. Normalize positions // 5. Normalize positions
const dimensions = normalizePositions(nodes, { isContainer: options.isContainer }) let dimensions = normalizePositions(nodes, { isContainer: options.isContainer })
// 6. Snap to grid if gridSize is specified (recalculates dimensions)
const snappedDimensions = snapNodesToGrid(nodes, layoutOptions.gridSize)
if (snappedDimensions) {
dimensions = snappedDimensions
}
return { nodes, dimensions } return { nodes, dimensions }
} }

View File

@@ -36,14 +36,13 @@ export function applyAutoLayout(
const horizontalSpacing = options.horizontalSpacing ?? DEFAULT_HORIZONTAL_SPACING const horizontalSpacing = options.horizontalSpacing ?? DEFAULT_HORIZONTAL_SPACING
const verticalSpacing = options.verticalSpacing ?? DEFAULT_VERTICAL_SPACING const verticalSpacing = options.verticalSpacing ?? DEFAULT_VERTICAL_SPACING
// Pre-calculate container dimensions by laying out their children (bottom-up)
// This ensures accurate widths/heights before root-level layout
prepareContainerDimensions( prepareContainerDimensions(
blocksCopy, blocksCopy,
edges, edges,
layoutBlocksCore, layoutBlocksCore,
horizontalSpacing, horizontalSpacing,
verticalSpacing verticalSpacing,
options.gridSize
) )
const { root: rootBlockIds } = getBlocksByParent(blocksCopy) const { root: rootBlockIds } = getBlocksByParent(blocksCopy)
@@ -58,8 +57,6 @@ export function applyAutoLayout(
(edge) => layoutRootIds.includes(edge.source) && layoutRootIds.includes(edge.target) (edge) => layoutRootIds.includes(edge.source) && layoutRootIds.includes(edge.target)
) )
// Calculate subflow depths before laying out root blocks
// This ensures blocks connected to subflow ends are positioned correctly
const subflowDepths = calculateSubflowDepths(blocksCopy, edges, assignLayers) const subflowDepths = calculateSubflowDepths(blocksCopy, edges, assignLayers)
if (Object.keys(rootBlocks).length > 0) { if (Object.keys(rootBlocks).length > 0) {
@@ -95,13 +92,12 @@ export function applyAutoLayout(
} }
export type { TargetedLayoutOptions } from '@/lib/workflows/autolayout/targeted' export type { TargetedLayoutOptions } from '@/lib/workflows/autolayout/targeted'
// Function exports
export { applyTargetedLayout } from '@/lib/workflows/autolayout/targeted' export { applyTargetedLayout } from '@/lib/workflows/autolayout/targeted'
// Type exports
export type { Edge, LayoutOptions, LayoutResult } from '@/lib/workflows/autolayout/types' export type { Edge, LayoutOptions, LayoutResult } from '@/lib/workflows/autolayout/types'
export { export {
getBlockMetrics, getBlockMetrics,
isContainerType, isContainerType,
shouldSkipAutoLayout, shouldSkipAutoLayout,
snapPositionToGrid,
transferBlockHeights, transferBlockHeights,
} from '@/lib/workflows/autolayout/utils' } from '@/lib/workflows/autolayout/utils'

View File

@@ -1,4 +1,3 @@
import { createLogger } from '@sim/logger'
import { import {
CONTAINER_PADDING, CONTAINER_PADDING,
DEFAULT_HORIZONTAL_SPACING, DEFAULT_HORIZONTAL_SPACING,
@@ -14,12 +13,11 @@ import {
isContainerType, isContainerType,
prepareContainerDimensions, prepareContainerDimensions,
shouldSkipAutoLayout, shouldSkipAutoLayout,
snapPositionToGrid,
} from '@/lib/workflows/autolayout/utils' } from '@/lib/workflows/autolayout/utils'
import { CONTAINER_DIMENSIONS } from '@/lib/workflows/blocks/block-dimensions' import { CONTAINER_DIMENSIONS } from '@/lib/workflows/blocks/block-dimensions'
import type { BlockState } from '@/stores/workflows/workflow/types' import type { BlockState } from '@/stores/workflows/workflow/types'
const logger = createLogger('AutoLayout:Targeted')
export interface TargetedLayoutOptions extends LayoutOptions { export interface TargetedLayoutOptions extends LayoutOptions {
changedBlockIds: string[] changedBlockIds: string[]
verticalSpacing?: number verticalSpacing?: number
@@ -39,6 +37,7 @@ export function applyTargetedLayout(
changedBlockIds, changedBlockIds,
verticalSpacing = DEFAULT_VERTICAL_SPACING, verticalSpacing = DEFAULT_VERTICAL_SPACING,
horizontalSpacing = DEFAULT_HORIZONTAL_SPACING, horizontalSpacing = DEFAULT_HORIZONTAL_SPACING,
gridSize,
} = options } = options
if (!changedBlockIds || changedBlockIds.length === 0) { if (!changedBlockIds || changedBlockIds.length === 0) {
@@ -48,19 +47,17 @@ export function applyTargetedLayout(
const changedSet = new Set(changedBlockIds) const changedSet = new Set(changedBlockIds)
const blocksCopy: Record<string, BlockState> = JSON.parse(JSON.stringify(blocks)) const blocksCopy: Record<string, BlockState> = JSON.parse(JSON.stringify(blocks))
// Pre-calculate container dimensions by laying out their children (bottom-up)
// This ensures accurate widths/heights before root-level layout
prepareContainerDimensions( prepareContainerDimensions(
blocksCopy, blocksCopy,
edges, edges,
layoutBlocksCore, layoutBlocksCore,
horizontalSpacing, horizontalSpacing,
verticalSpacing verticalSpacing,
gridSize
) )
const groups = getBlocksByParent(blocksCopy) const groups = getBlocksByParent(blocksCopy)
// Calculate subflow depths before layout to properly position blocks after subflow ends
const subflowDepths = calculateSubflowDepths(blocksCopy, edges, assignLayers) const subflowDepths = calculateSubflowDepths(blocksCopy, edges, assignLayers)
layoutGroup( layoutGroup(
@@ -71,7 +68,8 @@ export function applyTargetedLayout(
changedSet, changedSet,
verticalSpacing, verticalSpacing,
horizontalSpacing, horizontalSpacing,
subflowDepths subflowDepths,
gridSize
) )
for (const [parentId, childIds] of groups.children.entries()) { for (const [parentId, childIds] of groups.children.entries()) {
@@ -83,7 +81,8 @@ export function applyTargetedLayout(
changedSet, changedSet,
verticalSpacing, verticalSpacing,
horizontalSpacing, horizontalSpacing,
subflowDepths subflowDepths,
gridSize
) )
} }
@@ -101,7 +100,8 @@ function layoutGroup(
changedSet: Set<string>, changedSet: Set<string>,
verticalSpacing: number, verticalSpacing: number,
horizontalSpacing: number, horizontalSpacing: number,
subflowDepths: Map<string, number> subflowDepths: Map<string, number>,
gridSize?: number
): void { ): void {
if (childIds.length === 0) return if (childIds.length === 0) return
@@ -116,7 +116,6 @@ function layoutGroup(
return return
} }
// Determine which blocks need repositioning
const requestedLayout = layoutEligibleChildIds.filter((id) => { const requestedLayout = layoutEligibleChildIds.filter((id) => {
const block = blocks[id] const block = blocks[id]
if (!block) return false if (!block) return false
@@ -141,7 +140,6 @@ function layoutGroup(
return return
} }
// Store old positions for anchor calculation
const oldPositions = new Map<string, { x: number; y: number }>() const oldPositions = new Map<string, { x: number; y: number }>()
for (const id of layoutEligibleChildIds) { for (const id of layoutEligibleChildIds) {
const block = blocks[id] const block = blocks[id]
@@ -149,8 +147,6 @@ function layoutGroup(
oldPositions.set(id, { ...block.position }) oldPositions.set(id, { ...block.position })
} }
// Compute layout positions using core function
// Only pass subflowDepths for root-level layout (not inside containers)
const layoutPositions = computeLayoutPositions( const layoutPositions = computeLayoutPositions(
layoutEligibleChildIds, layoutEligibleChildIds,
blocks, blocks,
@@ -158,7 +154,8 @@ function layoutGroup(
parentBlock, parentBlock,
horizontalSpacing, horizontalSpacing,
verticalSpacing, verticalSpacing,
parentId === null ? subflowDepths : undefined parentId === null ? subflowDepths : undefined,
gridSize
) )
if (layoutPositions.size === 0) { if (layoutPositions.size === 0) {
@@ -168,7 +165,6 @@ function layoutGroup(
return return
} }
// Find anchor block (unchanged block with a layout position)
let offsetX = 0 let offsetX = 0
let offsetY = 0 let offsetY = 0
@@ -185,20 +181,16 @@ function layoutGroup(
} }
} }
// Apply new positions only to blocks that need layout
for (const id of needsLayout) { for (const id of needsLayout) {
const block = blocks[id] const block = blocks[id]
const newPos = layoutPositions.get(id) const newPos = layoutPositions.get(id)
if (!block || !newPos) continue if (!block || !newPos) continue
block.position = { block.position = snapPositionToGrid({ x: newPos.x + offsetX, y: newPos.y + offsetY }, gridSize)
x: newPos.x + offsetX,
y: newPos.y + offsetY,
}
} }
} }
/** /**
* Computes layout positions for a subset of blocks using the core layout * Computes layout positions for a subset of blocks using the core layout function
*/ */
function computeLayoutPositions( function computeLayoutPositions(
childIds: string[], childIds: string[],
@@ -207,7 +199,8 @@ function computeLayoutPositions(
parentBlock: BlockState | undefined, parentBlock: BlockState | undefined,
horizontalSpacing: number, horizontalSpacing: number,
verticalSpacing: number, verticalSpacing: number,
subflowDepths?: Map<string, number> subflowDepths?: Map<string, number>,
gridSize?: number
): Map<string, { x: number; y: number }> { ): Map<string, { x: number; y: number }> {
const subsetBlocks: Record<string, BlockState> = {} const subsetBlocks: Record<string, BlockState> = {}
for (const id of childIds) { for (const id of childIds) {
@@ -228,11 +221,11 @@ function computeLayoutPositions(
layoutOptions: { layoutOptions: {
horizontalSpacing: isContainer ? horizontalSpacing * 0.85 : horizontalSpacing, horizontalSpacing: isContainer ? horizontalSpacing * 0.85 : horizontalSpacing,
verticalSpacing, verticalSpacing,
gridSize,
}, },
subflowDepths, subflowDepths,
}) })
// Update parent container dimensions if applicable
if (parentBlock) { if (parentBlock) {
parentBlock.data = { parentBlock.data = {
...parentBlock.data, ...parentBlock.data,
@@ -241,7 +234,6 @@ function computeLayoutPositions(
} }
} }
// Convert nodes to position map
const positions = new Map<string, { x: number; y: number }>() const positions = new Map<string, { x: number; y: number }>()
for (const node of nodes.values()) { for (const node of nodes.values()) {
positions.set(node.id, { x: node.position.x, y: node.position.y }) positions.set(node.id, { x: node.position.x, y: node.position.y })

View File

@@ -7,6 +7,7 @@ export interface LayoutOptions {
horizontalSpacing?: number horizontalSpacing?: number
verticalSpacing?: number verticalSpacing?: number
padding?: { x: number; y: number } padding?: { x: number; y: number }
gridSize?: number
} }
export interface LayoutResult { export interface LayoutResult {

View File

@@ -18,6 +18,61 @@ function resolveNumeric(value: number | undefined, fallback: number): number {
return typeof value === 'number' && Number.isFinite(value) ? value : fallback return typeof value === 'number' && Number.isFinite(value) ? value : fallback
} }
/**
* Snaps a single coordinate value to the nearest grid position
*/
function snapToGrid(value: number, gridSize: number): number {
return Math.round(value / gridSize) * gridSize
}
/**
* Snaps a position to the nearest grid point.
* Returns the original position if gridSize is 0 or not provided.
*/
export function snapPositionToGrid(
position: { x: number; y: number },
gridSize: number | undefined
): { x: number; y: number } {
if (!gridSize || gridSize <= 0) {
return position
}
return {
x: snapToGrid(position.x, gridSize),
y: snapToGrid(position.y, gridSize),
}
}
/**
* Snaps all node positions in a graph to grid positions and returns updated dimensions.
* Returns null if gridSize is not set or no snapping was needed.
*/
export function snapNodesToGrid(
nodes: Map<string, GraphNode>,
gridSize: number | undefined
): { width: number; height: number } | null {
if (!gridSize || gridSize <= 0 || nodes.size === 0) {
return null
}
let minX = Number.POSITIVE_INFINITY
let minY = Number.POSITIVE_INFINITY
let maxX = Number.NEGATIVE_INFINITY
let maxY = Number.NEGATIVE_INFINITY
for (const node of nodes.values()) {
node.position = snapPositionToGrid(node.position, gridSize)
minX = Math.min(minX, node.position.x)
minY = Math.min(minY, node.position.y)
maxX = Math.max(maxX, node.position.x + node.metrics.width)
maxY = Math.max(maxY, node.position.y + node.metrics.height)
}
return {
width: maxX - minX + CONTAINER_PADDING * 2,
height: maxY - minY + CONTAINER_PADDING * 2,
}
}
/** /**
* Checks if a block type is a container (loop or parallel) * Checks if a block type is a container (loop or parallel)
*/ */
@@ -314,6 +369,7 @@ export type LayoutFunction = (
horizontalSpacing?: number horizontalSpacing?: number
verticalSpacing?: number verticalSpacing?: number
padding?: { x: number; y: number } padding?: { x: number; y: number }
gridSize?: number
} }
subflowDepths?: Map<string, number> subflowDepths?: Map<string, number>
} }
@@ -329,13 +385,15 @@ export type LayoutFunction = (
* @param layoutFn - The layout function to use for calculating dimensions * @param layoutFn - The layout function to use for calculating dimensions
* @param horizontalSpacing - Horizontal spacing between blocks * @param horizontalSpacing - Horizontal spacing between blocks
* @param verticalSpacing - Vertical spacing between blocks * @param verticalSpacing - Vertical spacing between blocks
* @param gridSize - Optional grid size for snap-to-grid
*/ */
export function prepareContainerDimensions( export function prepareContainerDimensions(
blocks: Record<string, BlockState>, blocks: Record<string, BlockState>,
edges: Edge[], edges: Edge[],
layoutFn: LayoutFunction, layoutFn: LayoutFunction,
horizontalSpacing: number, horizontalSpacing: number,
verticalSpacing: number verticalSpacing: number,
gridSize?: number
): void { ): void {
const { children } = getBlocksByParent(blocks) const { children } = getBlocksByParent(blocks)
@@ -402,6 +460,7 @@ export function prepareContainerDimensions(
layoutOptions: { layoutOptions: {
horizontalSpacing: horizontalSpacing * 0.85, horizontalSpacing: horizontalSpacing * 0.85,
verticalSpacing, verticalSpacing,
gridSize,
}, },
}) })

View File

@@ -16,7 +16,12 @@ import {
USER_FILE_PROPERTY_TYPES, USER_FILE_PROPERTY_TYPES,
} from '@/lib/workflows/types' } from '@/lib/workflows/types'
import { getBlock } from '@/blocks' import { getBlock } from '@/blocks'
import type { BlockConfig, OutputCondition, OutputFieldDefinition } from '@/blocks/types' import {
type BlockConfig,
isHiddenFromDisplay,
type OutputCondition,
type OutputFieldDefinition,
} from '@/blocks/types'
import { getTool } from '@/tools/utils' import { getTool } from '@/tools/utils'
import { getTrigger, isTriggerValid } from '@/triggers' import { getTrigger, isTriggerValid } from '@/triggers'
@@ -86,8 +91,8 @@ function evaluateOutputCondition(
} }
/** /**
* Filters outputs based on their conditions. * Filters outputs based on their conditions and hiddenFromDisplay flag.
* Returns a new OutputDefinition with only the outputs whose conditions are met. * Returns a new OutputDefinition with only the outputs that should be shown.
*/ */
function filterOutputsByCondition( function filterOutputsByCondition(
outputs: OutputDefinition, outputs: OutputDefinition,
@@ -96,6 +101,8 @@ function filterOutputsByCondition(
const filtered: OutputDefinition = {} const filtered: OutputDefinition = {}
for (const [key, value] of Object.entries(outputs)) { for (const [key, value] of Object.entries(outputs)) {
if (isHiddenFromDisplay(value)) continue
if (!value || typeof value !== 'object' || !('condition' in value)) { if (!value || typeof value !== 'object' || !('condition' in value)) {
filtered[key] = value filtered[key] = value
continue continue
@@ -105,7 +112,7 @@ function filterOutputsByCondition(
const passes = !condition || evaluateOutputCondition(condition, subBlocks) const passes = !condition || evaluateOutputCondition(condition, subBlocks)
if (passes) { if (passes) {
const { condition: _, ...rest } = value const { condition: _, hiddenFromDisplay: __, ...rest } = value
filtered[key] = rest filtered[key] = rest
} }
} }
@@ -259,50 +266,26 @@ export function getBlockOutputs(
} }
if (blockType === 'human_in_the_loop') { if (blockType === 'human_in_the_loop') {
const hitlOutputs: OutputDefinition = { // Start with block config outputs (respects hiddenFromDisplay via filterOutputsByCondition)
url: { type: 'string', description: 'Resume UI URL' }, const baseOutputs = filterOutputsByCondition(
resumeEndpoint: { { ...(blockConfig.outputs || {}) } as OutputDefinition,
type: 'string', subBlocks
description: 'Resume API endpoint URL for direct curl requests', )
},
}
// Add inputFormat fields (resume form fields)
const normalizedInputFormat = normalizeInputFormatValue(subBlocks?.inputFormat?.value) const normalizedInputFormat = normalizeInputFormatValue(subBlocks?.inputFormat?.value)
for (const field of normalizedInputFormat) { for (const field of normalizedInputFormat) {
const fieldName = field?.name?.trim() const fieldName = field?.name?.trim()
if (!fieldName) continue if (!fieldName) continue
hitlOutputs[fieldName] = { baseOutputs[fieldName] = {
type: (field?.type || 'any') as any, type: (field?.type || 'any') as any,
description: `Field from resume form`, description: field?.description || `Field from resume form`,
} }
} }
return hitlOutputs return baseOutputs
}
if (blockType === 'approval') {
// Start with only url (apiUrl commented out - not accessible as output)
const pauseResumeOutputs: OutputDefinition = {
url: { type: 'string', description: 'Resume UI URL' },
// apiUrl: { type: 'string', description: 'Resume API URL' }, // Commented out - not accessible as output
}
const normalizedInputFormat = normalizeInputFormatValue(subBlocks?.inputFormat?.value)
// Add each input format field as a top-level output
for (const field of normalizedInputFormat) {
const fieldName = field?.name?.trim()
if (!fieldName) continue
pauseResumeOutputs[fieldName] = {
type: (field?.type || 'any') as any,
description: `Field from input format`,
}
}
return pauseResumeOutputs
} }
if (startPath === StartBlockPath.LEGACY_STARTER) { if (startPath === StartBlockPath.LEGACY_STARTER) {

View File

@@ -9,6 +9,7 @@ import { LoggingSession } from '@/lib/logs/execution/logging-session'
import { executeWorkflowCore } from '@/lib/workflows/executor/execution-core' import { executeWorkflowCore } from '@/lib/workflows/executor/execution-core'
import { ExecutionSnapshot } from '@/executor/execution/snapshot' import { ExecutionSnapshot } from '@/executor/execution/snapshot'
import type { ExecutionResult, PausePoint, SerializedSnapshot } from '@/executor/types' import type { ExecutionResult, PausePoint, SerializedSnapshot } from '@/executor/types'
import { filterOutputForLog } from '@/executor/utils/output-filter'
import type { SerializedConnection } from '@/serializer/types' import type { SerializedConnection } from '@/serializer/types'
const logger = createLogger('HumanInTheLoopManager') const logger = createLogger('HumanInTheLoopManager')
@@ -576,13 +577,11 @@ export class PauseResumeManager {
log.blockId === contextId log.blockId === contextId
) )
if (blockLogIndex !== -1) { if (blockLogIndex !== -1) {
// Filter output for logging (exclude internal fields and response) // Filter output for logging using shared utility
const filteredOutput: Record<string, unknown> = {} // 'resume' is redundant with url/resumeEndpoint so we filter it out
for (const [key, value] of Object.entries(mergedOutput)) { const filteredOutput = filterOutputForLog('human_in_the_loop', mergedOutput, {
if (key.startsWith('_')) continue additionalHiddenKeys: ['resume'],
if (key === 'response') continue })
filteredOutput[key] = value
}
stateCopy.blockLogs[blockLogIndex] = { stateCopy.blockLogs[blockLogIndex] = {
...stateCopy.blockLogs[blockLogIndex], ...stateCopy.blockLogs[blockLogIndex],
blockId: stateBlockKey, blockId: stateBlockKey,

View File

@@ -102,7 +102,7 @@ export const azureOpenAIProvider: ProviderConfig = {
} }
if (request.temperature !== undefined) payload.temperature = request.temperature if (request.temperature !== undefined) payload.temperature = request.temperature
if (request.maxTokens !== undefined) payload.max_tokens = request.maxTokens if (request.maxTokens != null) payload.max_completion_tokens = request.maxTokens
if (request.reasoningEffort !== undefined) payload.reasoning_effort = request.reasoningEffort if (request.reasoningEffort !== undefined) payload.reasoning_effort = request.reasoningEffort
if (request.verbosity !== undefined) payload.verbosity = request.verbosity if (request.verbosity !== undefined) payload.verbosity = request.verbosity

View File

@@ -77,7 +77,7 @@ export const cerebrasProvider: ProviderConfig = {
messages: allMessages, messages: allMessages,
} }
if (request.temperature !== undefined) payload.temperature = request.temperature if (request.temperature !== undefined) payload.temperature = request.temperature
if (request.maxTokens !== undefined) payload.max_tokens = request.maxTokens if (request.maxTokens != null) payload.max_completion_tokens = request.maxTokens
if (request.responseFormat) { if (request.responseFormat) {
payload.response_format = { payload.response_format = {
type: 'json_schema', type: 'json_schema',

View File

@@ -81,7 +81,7 @@ export const deepseekProvider: ProviderConfig = {
} }
if (request.temperature !== undefined) payload.temperature = request.temperature if (request.temperature !== undefined) payload.temperature = request.temperature
if (request.maxTokens !== undefined) payload.max_tokens = request.maxTokens if (request.maxTokens != null) payload.max_tokens = request.maxTokens
let preparedTools: ReturnType<typeof prepareToolsWithUsageControl> | null = null let preparedTools: ReturnType<typeof prepareToolsWithUsageControl> | null = null

View File

@@ -349,7 +349,7 @@ export async function executeGeminiRequest(
if (request.temperature !== undefined) { if (request.temperature !== undefined) {
geminiConfig.temperature = request.temperature geminiConfig.temperature = request.temperature
} }
if (request.maxTokens !== undefined) { if (request.maxTokens != null) {
geminiConfig.maxOutputTokens = request.maxTokens geminiConfig.maxOutputTokens = request.maxTokens
} }
if (systemInstruction) { if (systemInstruction) {

View File

@@ -123,17 +123,21 @@ export function extractFunctionCallPart(candidate: Candidate | undefined): Part
} }
/** /**
* Converts usage metadata from SDK response to our format * Converts usage metadata from SDK response to our format.
* Per Gemini docs, total = promptTokenCount + candidatesTokenCount + toolUsePromptTokenCount + thoughtsTokenCount
* We include toolUsePromptTokenCount in input and thoughtsTokenCount in output for correct billing.
*/ */
export function convertUsageMetadata( export function convertUsageMetadata(
usageMetadata: GenerateContentResponseUsageMetadata | undefined usageMetadata: GenerateContentResponseUsageMetadata | undefined
): GeminiUsage { ): GeminiUsage {
const promptTokenCount = usageMetadata?.promptTokenCount ?? 0 const thoughtsTokenCount = usageMetadata?.thoughtsTokenCount ?? 0
const candidatesTokenCount = usageMetadata?.candidatesTokenCount ?? 0 const toolUsePromptTokenCount = usageMetadata?.toolUsePromptTokenCount ?? 0
const promptTokenCount = (usageMetadata?.promptTokenCount ?? 0) + toolUsePromptTokenCount
const candidatesTokenCount = (usageMetadata?.candidatesTokenCount ?? 0) + thoughtsTokenCount
return { return {
promptTokenCount, promptTokenCount,
candidatesTokenCount, candidatesTokenCount,
totalTokenCount: usageMetadata?.totalTokenCount ?? promptTokenCount + candidatesTokenCount, totalTokenCount: usageMetadata?.totalTokenCount ?? 0,
} }
} }

View File

@@ -74,7 +74,7 @@ export const groqProvider: ProviderConfig = {
} }
if (request.temperature !== undefined) payload.temperature = request.temperature if (request.temperature !== undefined) payload.temperature = request.temperature
if (request.maxTokens !== undefined) payload.max_tokens = request.maxTokens if (request.maxTokens != null) payload.max_completion_tokens = request.maxTokens
if (request.responseFormat) { if (request.responseFormat) {
payload.response_format = { payload.response_format = {

View File

@@ -91,7 +91,7 @@ export const mistralProvider: ProviderConfig = {
} }
if (request.temperature !== undefined) payload.temperature = request.temperature if (request.temperature !== undefined) payload.temperature = request.temperature
if (request.maxTokens !== undefined) payload.max_tokens = request.maxTokens if (request.maxTokens != null) payload.max_tokens = request.maxTokens
if (request.responseFormat) { if (request.responseFormat) {
payload.response_format = { payload.response_format = {

View File

@@ -1130,7 +1130,7 @@ export const PROVIDER_DEFINITIONS: Record<string, ProviderDefinition> = {
id: 'cerebras', id: 'cerebras',
name: 'Cerebras', name: 'Cerebras',
description: 'Cerebras Cloud LLMs', description: 'Cerebras Cloud LLMs',
defaultModel: 'cerebras/llama-3.3-70b', defaultModel: 'cerebras/gpt-oss-120b',
modelPatterns: [/^cerebras/], modelPatterns: [/^cerebras/],
icon: CerebrasIcon, icon: CerebrasIcon,
capabilities: { capabilities: {
@@ -1138,44 +1138,64 @@ export const PROVIDER_DEFINITIONS: Record<string, ProviderDefinition> = {
}, },
models: [ models: [
{ {
id: 'cerebras/llama-3.1-8b', id: 'cerebras/gpt-oss-120b',
pricing: {
input: 0.35,
output: 0.75,
updatedAt: '2026-01-27',
},
capabilities: {},
contextWindow: 131000,
},
{
id: 'cerebras/llama3.1-8b',
pricing: { pricing: {
input: 0.1, input: 0.1,
output: 0.1, output: 0.1,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
}, },
capabilities: {}, capabilities: {},
contextWindow: 32000, contextWindow: 32000,
}, },
{
id: 'cerebras/llama-3.1-70b',
pricing: {
input: 0.6,
output: 0.6,
updatedAt: '2025-10-11',
},
capabilities: {},
contextWindow: 128000,
},
{ {
id: 'cerebras/llama-3.3-70b', id: 'cerebras/llama-3.3-70b',
pricing: { pricing: {
input: 0.6, input: 0.85,
output: 0.6, output: 1.2,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
}, },
capabilities: {}, capabilities: {},
contextWindow: 128000, contextWindow: 128000,
}, },
{ {
id: 'cerebras/llama-4-scout-17b-16e-instruct', id: 'cerebras/qwen-3-32b',
pricing: { pricing: {
input: 0.11, input: 0.4,
output: 0.34, output: 0.8,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
}, },
capabilities: {}, capabilities: {},
contextWindow: 10000000, contextWindow: 131000,
},
{
id: 'cerebras/qwen-3-235b-a22b-instruct-2507',
pricing: {
input: 0.6,
output: 1.2,
updatedAt: '2026-01-27',
},
capabilities: {},
contextWindow: 131000,
},
{
id: 'cerebras/zai-glm-4.7',
pricing: {
input: 2.25,
output: 2.75,
updatedAt: '2026-01-27',
},
capabilities: {},
contextWindow: 131000,
}, },
], ],
}, },
@@ -1194,8 +1214,8 @@ export const PROVIDER_DEFINITIONS: Record<string, ProviderDefinition> = {
id: 'groq/openai/gpt-oss-120b', id: 'groq/openai/gpt-oss-120b',
pricing: { pricing: {
input: 0.15, input: 0.15,
output: 0.75, output: 0.6,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
}, },
capabilities: {}, capabilities: {},
contextWindow: 131072, contextWindow: 131072,
@@ -1203,9 +1223,29 @@ export const PROVIDER_DEFINITIONS: Record<string, ProviderDefinition> = {
{ {
id: 'groq/openai/gpt-oss-20b', id: 'groq/openai/gpt-oss-20b',
pricing: { pricing: {
input: 0.01, input: 0.075,
output: 0.25, output: 0.3,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
},
capabilities: {},
contextWindow: 131072,
},
{
id: 'groq/openai/gpt-oss-safeguard-20b',
pricing: {
input: 0.075,
output: 0.3,
updatedAt: '2026-01-27',
},
capabilities: {},
contextWindow: 131072,
},
{
id: 'groq/qwen/qwen3-32b',
pricing: {
input: 0.29,
output: 0.59,
updatedAt: '2026-01-27',
}, },
capabilities: {}, capabilities: {},
contextWindow: 131072, contextWindow: 131072,
@@ -1215,7 +1255,7 @@ export const PROVIDER_DEFINITIONS: Record<string, ProviderDefinition> = {
pricing: { pricing: {
input: 0.05, input: 0.05,
output: 0.08, output: 0.08,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
}, },
capabilities: {}, capabilities: {},
contextWindow: 131072, contextWindow: 131072,
@@ -1225,27 +1265,17 @@ export const PROVIDER_DEFINITIONS: Record<string, ProviderDefinition> = {
pricing: { pricing: {
input: 0.59, input: 0.59,
output: 0.79, output: 0.79,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
}, },
capabilities: {}, capabilities: {},
contextWindow: 131072, contextWindow: 131072,
}, },
{ {
id: 'groq/llama-4-scout-17b-instruct', id: 'groq/meta-llama/llama-4-scout-17b-16e-instruct',
pricing: { pricing: {
input: 0.11, input: 0.11,
output: 0.34, output: 0.34,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
},
capabilities: {},
contextWindow: 131072,
},
{
id: 'groq/llama-4-maverick-17b-instruct',
pricing: {
input: 0.5,
output: 0.77,
updatedAt: '2025-10-11',
}, },
capabilities: {}, capabilities: {},
contextWindow: 131072, contextWindow: 131072,
@@ -1253,9 +1283,9 @@ export const PROVIDER_DEFINITIONS: Record<string, ProviderDefinition> = {
{ {
id: 'groq/meta-llama/llama-4-maverick-17b-128e-instruct', id: 'groq/meta-llama/llama-4-maverick-17b-128e-instruct',
pricing: { pricing: {
input: 0.5, input: 0.2,
output: 0.77, output: 0.6,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
}, },
capabilities: {}, capabilities: {},
contextWindow: 131072, contextWindow: 131072,
@@ -1265,7 +1295,7 @@ export const PROVIDER_DEFINITIONS: Record<string, ProviderDefinition> = {
pricing: { pricing: {
input: 0.04, input: 0.04,
output: 0.04, output: 0.04,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
}, },
capabilities: {}, capabilities: {},
contextWindow: 8192, contextWindow: 8192,
@@ -1275,27 +1305,37 @@ export const PROVIDER_DEFINITIONS: Record<string, ProviderDefinition> = {
pricing: { pricing: {
input: 0.59, input: 0.59,
output: 0.79, output: 0.79,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
}, },
capabilities: {}, capabilities: {},
contextWindow: 128000, contextWindow: 128000,
}, },
{ {
id: 'groq/moonshotai/kimi-k2-instruct', id: 'groq/deepseek-r1-distill-qwen-32b',
pricing: {
input: 0.69,
output: 0.69,
updatedAt: '2026-01-27',
},
capabilities: {},
contextWindow: 128000,
},
{
id: 'groq/moonshotai/kimi-k2-instruct-0905',
pricing: { pricing: {
input: 1.0, input: 1.0,
output: 3.0, output: 3.0,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
}, },
capabilities: {}, capabilities: {},
contextWindow: 131072, contextWindow: 262144,
}, },
{ {
id: 'groq/meta-llama/llama-guard-4-12b', id: 'groq/meta-llama/llama-guard-4-12b',
pricing: { pricing: {
input: 0.2, input: 0.2,
output: 0.2, output: 0.2,
updatedAt: '2025-10-11', updatedAt: '2026-01-27',
}, },
capabilities: {}, capabilities: {},
contextWindow: 131072, contextWindow: 131072,

View File

@@ -105,7 +105,7 @@ export const ollamaProvider: ProviderConfig = {
} }
if (request.temperature !== undefined) payload.temperature = request.temperature if (request.temperature !== undefined) payload.temperature = request.temperature
if (request.maxTokens !== undefined) payload.max_tokens = request.maxTokens if (request.maxTokens != null) payload.max_tokens = request.maxTokens
if (request.responseFormat) { if (request.responseFormat) {
payload.response_format = { payload.response_format = {

View File

@@ -81,7 +81,7 @@ export const openaiProvider: ProviderConfig = {
} }
if (request.temperature !== undefined) payload.temperature = request.temperature if (request.temperature !== undefined) payload.temperature = request.temperature
if (request.maxTokens !== undefined) payload.max_tokens = request.maxTokens if (request.maxTokens != null) payload.max_completion_tokens = request.maxTokens
if (request.reasoningEffort !== undefined) payload.reasoning_effort = request.reasoningEffort if (request.reasoningEffort !== undefined) payload.reasoning_effort = request.reasoningEffort
if (request.verbosity !== undefined) payload.verbosity = request.verbosity if (request.verbosity !== undefined) payload.verbosity = request.verbosity

View File

@@ -121,7 +121,7 @@ export const openRouterProvider: ProviderConfig = {
} }
if (request.temperature !== undefined) payload.temperature = request.temperature if (request.temperature !== undefined) payload.temperature = request.temperature
if (request.maxTokens !== undefined) payload.max_tokens = request.maxTokens if (request.maxTokens != null) payload.max_tokens = request.maxTokens
let preparedTools: ReturnType<typeof prepareToolsWithUsageControl> | null = null let preparedTools: ReturnType<typeof prepareToolsWithUsageControl> | null = null
let hasActiveTools = false let hasActiveTools = false
@@ -516,7 +516,7 @@ export const openRouterProvider: ProviderConfig = {
return streamingResult as StreamingExecution return streamingResult as StreamingExecution
} }
if (request.responseFormat && hasActiveTools && toolCalls.length > 0) { if (request.responseFormat && hasActiveTools) {
const finalPayload: any = { const finalPayload: any = {
model: payload.model, model: payload.model,
messages: [...currentMessages], messages: [...currentMessages],

View File

@@ -135,7 +135,7 @@ export const vllmProvider: ProviderConfig = {
} }
if (request.temperature !== undefined) payload.temperature = request.temperature if (request.temperature !== undefined) payload.temperature = request.temperature
if (request.maxTokens !== undefined) payload.max_tokens = request.maxTokens if (request.maxTokens != null) payload.max_completion_tokens = request.maxTokens
if (request.responseFormat) { if (request.responseFormat) {
payload.response_format = { payload.response_format = {

View File

@@ -92,7 +92,7 @@ export const xAIProvider: ProviderConfig = {
} }
if (request.temperature !== undefined) basePayload.temperature = request.temperature if (request.temperature !== undefined) basePayload.temperature = request.temperature
if (request.maxTokens !== undefined) basePayload.max_tokens = request.maxTokens if (request.maxTokens != null) basePayload.max_completion_tokens = request.maxTokens
let preparedTools: ReturnType<typeof prepareToolsWithUsageControl> | null = null let preparedTools: ReturnType<typeof prepareToolsWithUsageControl> | null = null
if (tools?.length) { if (tools?.length) {

View File

@@ -0,0 +1,146 @@
import { createLogger } from '@sim/logger'
import type {
ClerkApiError,
ClerkCreateOrganizationParams,
ClerkCreateOrganizationResponse,
ClerkOrganization,
} from '@/tools/clerk/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('ClerkCreateOrganization')
export const clerkCreateOrganizationTool: ToolConfig<
ClerkCreateOrganizationParams,
ClerkCreateOrganizationResponse
> = {
id: 'clerk_create_organization',
name: 'Create Organization in Clerk',
description: 'Create a new organization in your Clerk application',
version: '1.0.0',
params: {
secretKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'The Clerk Secret Key for API authentication',
},
name: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Name of the organization',
},
createdBy: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'User ID of the creator (will become admin)',
},
slug: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Slug identifier for the organization',
},
maxAllowedMemberships: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum member capacity (0 for unlimited)',
},
publicMetadata: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Public metadata (JSON object)',
},
privateMetadata: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Private metadata (JSON object)',
},
},
request: {
url: () => 'https://api.clerk.com/v1/organizations',
method: 'POST',
headers: (params) => {
if (!params.secretKey) {
throw new Error('Clerk Secret Key is required')
}
return {
Authorization: `Bearer ${params.secretKey}`,
'Content-Type': 'application/json',
}
},
body: (params) => {
const body: Record<string, unknown> = {
name: params.name,
created_by: params.createdBy,
}
if (params.slug) body.slug = params.slug
if (params.maxAllowedMemberships !== undefined)
body.max_allowed_memberships = params.maxAllowedMemberships
if (params.publicMetadata) body.public_metadata = params.publicMetadata
if (params.privateMetadata) body.private_metadata = params.privateMetadata
return body
},
},
transformResponse: async (response: Response) => {
const data: ClerkOrganization | ClerkApiError = await response.json()
if (!response.ok) {
logger.error('Clerk API request failed', { data, status: response.status })
throw new Error(
(data as ClerkApiError).errors?.[0]?.message || 'Failed to create organization in Clerk'
)
}
const org = data as ClerkOrganization
return {
success: true,
output: {
id: org.id,
name: org.name,
slug: org.slug ?? null,
imageUrl: org.image_url ?? null,
hasImage: org.has_image ?? false,
membersCount: org.members_count ?? null,
pendingInvitationsCount: org.pending_invitations_count ?? null,
maxAllowedMemberships: org.max_allowed_memberships ?? 0,
adminDeleteEnabled: org.admin_delete_enabled ?? false,
createdBy: org.created_by ?? null,
createdAt: org.created_at,
updatedAt: org.updated_at,
publicMetadata: org.public_metadata ?? {},
success: true,
},
}
},
outputs: {
id: { type: 'string', description: 'Created organization ID' },
name: { type: 'string', description: 'Organization name' },
slug: { type: 'string', description: 'Organization slug', optional: true },
imageUrl: { type: 'string', description: 'Organization image URL', optional: true },
hasImage: { type: 'boolean', description: 'Whether organization has an image' },
membersCount: { type: 'number', description: 'Number of members', optional: true },
pendingInvitationsCount: {
type: 'number',
description: 'Number of pending invitations',
optional: true,
},
maxAllowedMemberships: { type: 'number', description: 'Max allowed memberships' },
adminDeleteEnabled: { type: 'boolean', description: 'Whether admin delete is enabled' },
createdBy: { type: 'string', description: 'Creator user ID', optional: true },
createdAt: { type: 'number', description: 'Creation timestamp' },
updatedAt: { type: 'number', description: 'Last update timestamp' },
publicMetadata: { type: 'json', description: 'Public metadata' },
success: { type: 'boolean', description: 'Operation success status' },
},
}

View File

@@ -0,0 +1,227 @@
import { createLogger } from '@sim/logger'
import type {
ClerkApiError,
ClerkCreateUserParams,
ClerkCreateUserResponse,
ClerkEmailAddress,
ClerkPhoneNumber,
ClerkUser,
} from '@/tools/clerk/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('ClerkCreateUser')
export const clerkCreateUserTool: ToolConfig<ClerkCreateUserParams, ClerkCreateUserResponse> = {
id: 'clerk_create_user',
name: 'Create User in Clerk',
description: 'Create a new user in your Clerk application',
version: '1.0.0',
params: {
secretKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'The Clerk Secret Key for API authentication',
},
emailAddress: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Email addresses for the user (comma-separated for multiple)',
},
phoneNumber: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Phone numbers for the user (comma-separated for multiple)',
},
username: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Username for the user (must be unique)',
},
password: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Password for the user (minimum 8 characters)',
},
firstName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'First name of the user',
},
lastName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Last name of the user',
},
externalId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'External system identifier (must be unique)',
},
publicMetadata: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Public metadata (JSON object, readable from frontend)',
},
privateMetadata: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Private metadata (JSON object, backend only)',
},
unsafeMetadata: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Unsafe metadata (JSON object, modifiable from frontend)',
},
skipPasswordChecks: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Skip password validation checks',
},
skipPasswordRequirement: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Make password optional',
},
},
request: {
url: () => 'https://api.clerk.com/v1/users',
method: 'POST',
headers: (params) => {
if (!params.secretKey) {
throw new Error('Clerk Secret Key is required')
}
return {
Authorization: `Bearer ${params.secretKey}`,
'Content-Type': 'application/json',
}
},
body: (params) => {
const body: Record<string, unknown> = {}
if (params.emailAddress) {
const emailStr = params.emailAddress as string
body.email_address = emailStr.split(',').map((e) => e.trim())
}
if (params.phoneNumber) {
const phoneStr = params.phoneNumber as string
body.phone_number = phoneStr.split(',').map((p) => p.trim())
}
if (params.username) body.username = params.username.trim()
if (params.password) body.password = params.password
if (params.firstName) body.first_name = params.firstName.trim()
if (params.lastName) body.last_name = params.lastName.trim()
if (params.externalId) body.external_id = params.externalId.trim()
if (params.publicMetadata) body.public_metadata = params.publicMetadata
if (params.privateMetadata) body.private_metadata = params.privateMetadata
if (params.unsafeMetadata) body.unsafe_metadata = params.unsafeMetadata
if (params.skipPasswordChecks !== undefined)
body.skip_password_checks = params.skipPasswordChecks
if (params.skipPasswordRequirement !== undefined)
body.skip_password_requirement = params.skipPasswordRequirement
return body
},
},
transformResponse: async (response: Response) => {
const data: ClerkUser | ClerkApiError = await response.json()
if (!response.ok) {
logger.error('Clerk API request failed', { data, status: response.status })
throw new Error(
(data as ClerkApiError).errors?.[0]?.message || 'Failed to create user in Clerk'
)
}
const user = data as ClerkUser
return {
success: true,
output: {
id: user.id,
username: user.username ?? null,
firstName: user.first_name ?? null,
lastName: user.last_name ?? null,
imageUrl: user.image_url ?? null,
primaryEmailAddressId: user.primary_email_address_id ?? null,
primaryPhoneNumberId: user.primary_phone_number_id ?? null,
emailAddresses: (user.email_addresses ?? []).map((email: ClerkEmailAddress) => ({
id: email.id,
emailAddress: email.email_address,
verified: email.verification?.status === 'verified',
})),
phoneNumbers: (user.phone_numbers ?? []).map((phone: ClerkPhoneNumber) => ({
id: phone.id,
phoneNumber: phone.phone_number,
verified: phone.verification?.status === 'verified',
})),
externalId: user.external_id ?? null,
createdAt: user.created_at,
updatedAt: user.updated_at,
publicMetadata: user.public_metadata ?? {},
success: true,
},
}
},
outputs: {
id: { type: 'string', description: 'Created user ID' },
username: { type: 'string', description: 'Username', optional: true },
firstName: { type: 'string', description: 'First name', optional: true },
lastName: { type: 'string', description: 'Last name', optional: true },
imageUrl: { type: 'string', description: 'Profile image URL', optional: true },
primaryEmailAddressId: {
type: 'string',
description: 'Primary email address ID',
optional: true,
},
primaryPhoneNumberId: {
type: 'string',
description: 'Primary phone number ID',
optional: true,
},
emailAddresses: {
type: 'array',
description: 'User email addresses',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Email address ID' },
emailAddress: { type: 'string', description: 'Email address' },
verified: { type: 'boolean', description: 'Whether email is verified' },
},
},
},
phoneNumbers: {
type: 'array',
description: 'User phone numbers',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Phone number ID' },
phoneNumber: { type: 'string', description: 'Phone number' },
verified: { type: 'boolean', description: 'Whether phone is verified' },
},
},
},
externalId: { type: 'string', description: 'External system ID', optional: true },
createdAt: { type: 'number', description: 'Creation timestamp' },
updatedAt: { type: 'number', description: 'Last update timestamp' },
publicMetadata: { type: 'json', description: 'Public metadata' },
success: { type: 'boolean', description: 'Operation success status' },
},
}

View File

@@ -0,0 +1,75 @@
import { createLogger } from '@sim/logger'
import type {
ClerkApiError,
ClerkDeleteResponse,
ClerkDeleteUserParams,
ClerkDeleteUserResponse,
} from '@/tools/clerk/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('ClerkDeleteUser')
export const clerkDeleteUserTool: ToolConfig<ClerkDeleteUserParams, ClerkDeleteUserResponse> = {
id: 'clerk_delete_user',
name: 'Delete User from Clerk',
description: 'Delete a user from your Clerk application',
version: '1.0.0',
params: {
secretKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'The Clerk Secret Key for API authentication',
},
userId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the user to delete',
},
},
request: {
url: (params) => `https://api.clerk.com/v1/users/${params.userId?.trim()}`,
method: 'DELETE',
headers: (params) => {
if (!params.secretKey) {
throw new Error('Clerk Secret Key is required')
}
return {
Authorization: `Bearer ${params.secretKey}`,
'Content-Type': 'application/json',
}
},
},
transformResponse: async (response: Response) => {
const data: ClerkDeleteResponse | ClerkApiError = await response.json()
if (!response.ok) {
logger.error('Clerk API request failed', { data, status: response.status })
throw new Error(
(data as ClerkApiError).errors?.[0]?.message || 'Failed to delete user from Clerk'
)
}
const deleteData = data as ClerkDeleteResponse
return {
success: true,
output: {
id: deleteData.id,
object: deleteData.object ?? 'user',
deleted: deleteData.deleted ?? true,
success: true,
},
}
},
outputs: {
id: { type: 'string', description: 'Deleted user ID' },
object: { type: 'string', description: 'Object type (user)' },
deleted: { type: 'boolean', description: 'Whether the user was deleted' },
success: { type: 'boolean', description: 'Operation success status' },
},
}

View File

@@ -0,0 +1,102 @@
import { createLogger } from '@sim/logger'
import type {
ClerkApiError,
ClerkGetOrganizationParams,
ClerkGetOrganizationResponse,
ClerkOrganization,
} from '@/tools/clerk/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('ClerkGetOrganization')
export const clerkGetOrganizationTool: ToolConfig<
ClerkGetOrganizationParams,
ClerkGetOrganizationResponse
> = {
id: 'clerk_get_organization',
name: 'Get Organization from Clerk',
description: 'Retrieve a single organization by ID or slug from Clerk',
version: '1.0.0',
params: {
secretKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'The Clerk Secret Key for API authentication',
},
organizationId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID or slug of the organization to retrieve',
},
},
request: {
url: (params) => `https://api.clerk.com/v1/organizations/${params.organizationId}`,
method: 'GET',
headers: (params) => {
if (!params.secretKey) {
throw new Error('Clerk Secret Key is required')
}
return {
Authorization: `Bearer ${params.secretKey}`,
'Content-Type': 'application/json',
}
},
},
transformResponse: async (response: Response) => {
const data: ClerkOrganization | ClerkApiError = await response.json()
if (!response.ok) {
logger.error('Clerk API request failed', { data, status: response.status })
throw new Error(
(data as ClerkApiError).errors?.[0]?.message || 'Failed to get organization from Clerk'
)
}
const org = data as ClerkOrganization
return {
success: true,
output: {
id: org.id,
name: org.name,
slug: org.slug ?? null,
imageUrl: org.image_url ?? null,
hasImage: org.has_image ?? false,
membersCount: org.members_count ?? null,
pendingInvitationsCount: org.pending_invitations_count ?? null,
maxAllowedMemberships: org.max_allowed_memberships ?? 0,
adminDeleteEnabled: org.admin_delete_enabled ?? false,
createdBy: org.created_by ?? null,
createdAt: org.created_at,
updatedAt: org.updated_at,
publicMetadata: org.public_metadata ?? {},
success: true,
},
}
},
outputs: {
id: { type: 'string', description: 'Organization ID' },
name: { type: 'string', description: 'Organization name' },
slug: { type: 'string', description: 'Organization slug', optional: true },
imageUrl: { type: 'string', description: 'Organization image URL', optional: true },
hasImage: { type: 'boolean', description: 'Whether organization has an image' },
membersCount: { type: 'number', description: 'Number of members', optional: true },
pendingInvitationsCount: {
type: 'number',
description: 'Number of pending invitations',
optional: true,
},
maxAllowedMemberships: { type: 'number', description: 'Max allowed memberships' },
adminDeleteEnabled: { type: 'boolean', description: 'Whether admin delete is enabled' },
createdBy: { type: 'string', description: 'Creator user ID', optional: true },
createdAt: { type: 'number', description: 'Creation timestamp' },
updatedAt: { type: 'number', description: 'Last update timestamp' },
publicMetadata: { type: 'json', description: 'Public metadata' },
success: { type: 'boolean', description: 'Operation success status' },
},
}

View File

@@ -0,0 +1,93 @@
import { createLogger } from '@sim/logger'
import type {
ClerkApiError,
ClerkGetSessionParams,
ClerkGetSessionResponse,
ClerkSession,
} from '@/tools/clerk/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('ClerkGetSession')
export const clerkGetSessionTool: ToolConfig<ClerkGetSessionParams, ClerkGetSessionResponse> = {
id: 'clerk_get_session',
name: 'Get Session from Clerk',
description: 'Retrieve a single session by ID from Clerk',
version: '1.0.0',
params: {
secretKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'The Clerk Secret Key for API authentication',
},
sessionId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the session to retrieve',
},
},
request: {
url: (params) => `https://api.clerk.com/v1/sessions/${params.sessionId}`,
method: 'GET',
headers: (params) => {
if (!params.secretKey) {
throw new Error('Clerk Secret Key is required')
}
return {
Authorization: `Bearer ${params.secretKey}`,
'Content-Type': 'application/json',
}
},
},
transformResponse: async (response: Response) => {
const data: ClerkSession | ClerkApiError = await response.json()
if (!response.ok) {
logger.error('Clerk API request failed', { data, status: response.status })
throw new Error(
(data as ClerkApiError).errors?.[0]?.message || 'Failed to get session from Clerk'
)
}
const session = data as ClerkSession
return {
success: true,
output: {
id: session.id,
userId: session.user_id,
clientId: session.client_id,
status: session.status,
lastActiveAt: session.last_active_at ?? null,
lastActiveOrganizationId: session.last_active_organization_id ?? null,
expireAt: session.expire_at ?? null,
abandonAt: session.abandon_at ?? null,
createdAt: session.created_at,
updatedAt: session.updated_at,
success: true,
},
}
},
outputs: {
id: { type: 'string', description: 'Session ID' },
userId: { type: 'string', description: 'User ID' },
clientId: { type: 'string', description: 'Client ID' },
status: { type: 'string', description: 'Session status' },
lastActiveAt: { type: 'number', description: 'Last activity timestamp', optional: true },
lastActiveOrganizationId: {
type: 'string',
description: 'Last active organization ID',
optional: true,
},
expireAt: { type: 'number', description: 'Expiration timestamp', optional: true },
abandonAt: { type: 'number', description: 'Abandon timestamp', optional: true },
createdAt: { type: 'number', description: 'Creation timestamp' },
updatedAt: { type: 'number', description: 'Last update timestamp' },
success: { type: 'boolean', description: 'Operation success status' },
},
}

View File

@@ -0,0 +1,167 @@
import { createLogger } from '@sim/logger'
import type {
ClerkApiError,
ClerkEmailAddress,
ClerkGetUserParams,
ClerkGetUserResponse,
ClerkPhoneNumber,
ClerkUser,
} from '@/tools/clerk/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('ClerkGetUser')
export const clerkGetUserTool: ToolConfig<ClerkGetUserParams, ClerkGetUserResponse> = {
id: 'clerk_get_user',
name: 'Get User from Clerk',
description: 'Retrieve a single user by their ID from Clerk',
version: '1.0.0',
params: {
secretKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'The Clerk Secret Key for API authentication',
},
userId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the user to retrieve',
},
},
request: {
url: (params) => `https://api.clerk.com/v1/users/${params.userId?.trim()}`,
method: 'GET',
headers: (params) => {
if (!params.secretKey) {
throw new Error('Clerk Secret Key is required')
}
return {
Authorization: `Bearer ${params.secretKey}`,
'Content-Type': 'application/json',
}
},
},
transformResponse: async (response: Response) => {
const data: ClerkUser | ClerkApiError = await response.json()
if (!response.ok) {
logger.error('Clerk API request failed', { data, status: response.status })
throw new Error(
(data as ClerkApiError).errors?.[0]?.message || 'Failed to get user from Clerk'
)
}
const user = data as ClerkUser
return {
success: true,
output: {
id: user.id,
username: user.username ?? null,
firstName: user.first_name ?? null,
lastName: user.last_name ?? null,
imageUrl: user.image_url ?? null,
hasImage: user.has_image ?? false,
primaryEmailAddressId: user.primary_email_address_id ?? null,
primaryPhoneNumberId: user.primary_phone_number_id ?? null,
primaryWeb3WalletId: user.primary_web3_wallet_id ?? null,
emailAddresses: (user.email_addresses ?? []).map((email: ClerkEmailAddress) => ({
id: email.id,
emailAddress: email.email_address,
verified: email.verification?.status === 'verified',
})),
phoneNumbers: (user.phone_numbers ?? []).map((phone: ClerkPhoneNumber) => ({
id: phone.id,
phoneNumber: phone.phone_number,
verified: phone.verification?.status === 'verified',
})),
externalId: user.external_id ?? null,
passwordEnabled: user.password_enabled ?? false,
twoFactorEnabled: user.two_factor_enabled ?? false,
totpEnabled: user.totp_enabled ?? false,
backupCodeEnabled: user.backup_code_enabled ?? false,
banned: user.banned ?? false,
locked: user.locked ?? false,
deleteSelfEnabled: user.delete_self_enabled ?? false,
createOrganizationEnabled: user.create_organization_enabled ?? false,
lastSignInAt: user.last_sign_in_at ?? null,
lastActiveAt: user.last_active_at ?? null,
createdAt: user.created_at,
updatedAt: user.updated_at,
publicMetadata: user.public_metadata ?? {},
privateMetadata: user.private_metadata ?? {},
unsafeMetadata: user.unsafe_metadata ?? {},
success: true,
},
}
},
outputs: {
id: { type: 'string', description: 'User ID' },
username: { type: 'string', description: 'Username', optional: true },
firstName: { type: 'string', description: 'First name', optional: true },
lastName: { type: 'string', description: 'Last name', optional: true },
imageUrl: { type: 'string', description: 'Profile image URL', optional: true },
hasImage: { type: 'boolean', description: 'Whether user has a profile image' },
primaryEmailAddressId: {
type: 'string',
description: 'Primary email address ID',
optional: true,
},
primaryPhoneNumberId: {
type: 'string',
description: 'Primary phone number ID',
optional: true,
},
primaryWeb3WalletId: { type: 'string', description: 'Primary Web3 wallet ID', optional: true },
emailAddresses: {
type: 'array',
description: 'User email addresses',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Email address ID' },
emailAddress: { type: 'string', description: 'Email address' },
verified: { type: 'boolean', description: 'Whether email is verified' },
},
},
},
phoneNumbers: {
type: 'array',
description: 'User phone numbers',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Phone number ID' },
phoneNumber: { type: 'string', description: 'Phone number' },
verified: { type: 'boolean', description: 'Whether phone is verified' },
},
},
},
externalId: { type: 'string', description: 'External system ID', optional: true },
passwordEnabled: { type: 'boolean', description: 'Whether password is enabled' },
twoFactorEnabled: { type: 'boolean', description: 'Whether 2FA is enabled' },
totpEnabled: { type: 'boolean', description: 'Whether TOTP is enabled' },
backupCodeEnabled: { type: 'boolean', description: 'Whether backup codes are enabled' },
banned: { type: 'boolean', description: 'Whether user is banned' },
locked: { type: 'boolean', description: 'Whether user is locked' },
deleteSelfEnabled: { type: 'boolean', description: 'Whether user can delete themselves' },
createOrganizationEnabled: {
type: 'boolean',
description: 'Whether user can create organizations',
},
lastSignInAt: { type: 'number', description: 'Last sign-in timestamp', optional: true },
lastActiveAt: { type: 'number', description: 'Last activity timestamp', optional: true },
createdAt: { type: 'number', description: 'Creation timestamp' },
updatedAt: { type: 'number', description: 'Last update timestamp' },
publicMetadata: { type: 'json', description: 'Public metadata (readable from frontend)' },
privateMetadata: { type: 'json', description: 'Private metadata (backend only)' },
unsafeMetadata: { type: 'json', description: 'Unsafe metadata (modifiable from frontend)' },
success: { type: 'boolean', description: 'Operation success status' },
},
}

View File

@@ -0,0 +1,11 @@
export { clerkCreateOrganizationTool } from './create_organization'
export { clerkCreateUserTool } from './create_user'
export { clerkDeleteUserTool } from './delete_user'
export { clerkGetOrganizationTool } from './get_organization'
export { clerkGetSessionTool } from './get_session'
export { clerkGetUserTool } from './get_user'
export { clerkListOrganizationsTool } from './list_organizations'
export { clerkListSessionsTool } from './list_sessions'
export { clerkListUsersTool } from './list_users'
export { clerkRevokeSessionTool } from './revoke_session'
export { clerkUpdateUserTool } from './update_user'

View File

@@ -0,0 +1,157 @@
import { createLogger } from '@sim/logger'
import type {
ClerkApiError,
ClerkListOrganizationsParams,
ClerkListOrganizationsResponse,
ClerkOrganization,
} from '@/tools/clerk/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('ClerkListOrganizations')
export const clerkListOrganizationsTool: ToolConfig<
ClerkListOrganizationsParams,
ClerkListOrganizationsResponse
> = {
id: 'clerk_list_organizations',
name: 'List Organizations from Clerk',
description: 'List all organizations in your Clerk application with optional filtering',
version: '1.0.0',
params: {
secretKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'The Clerk Secret Key for API authentication',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of results per page (1-500, default: 10)',
},
offset: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of results to skip for pagination',
},
includeMembersCount: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Include member count for each organization',
},
query: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Search by organization ID, name, or slug',
},
orderBy: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Sort field (name, created_at, members_count) with +/- prefix',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.limit) queryParams.append('limit', params.limit.toString())
if (params.offset) queryParams.append('offset', params.offset.toString())
if (params.includeMembersCount) queryParams.append('include_members_count', 'true')
if (params.query) queryParams.append('query', params.query)
if (params.orderBy) queryParams.append('order_by', params.orderBy)
const queryString = queryParams.toString()
return queryString
? `https://api.clerk.com/v1/organizations?${queryString}`
: 'https://api.clerk.com/v1/organizations'
},
method: 'GET',
headers: (params) => {
if (!params.secretKey) {
throw new Error('Clerk Secret Key is required')
}
return {
Authorization: `Bearer ${params.secretKey}`,
'Content-Type': 'application/json',
}
},
},
transformResponse: async (response: Response) => {
const json: { data: ClerkOrganization[]; total_count: number } | ClerkApiError =
await response.json()
if (!response.ok) {
logger.error('Clerk API request failed', { data: json, status: response.status })
throw new Error(
(json as ClerkApiError).errors?.[0]?.message || 'Failed to list organizations from Clerk'
)
}
const responseData = json as { data: ClerkOrganization[]; total_count: number }
// Transform each organization to extract key fields
const organizations = responseData.data.map((org) => ({
id: org.id,
name: org.name,
slug: org.slug ?? null,
imageUrl: org.image_url ?? null,
hasImage: org.has_image ?? false,
membersCount: org.members_count ?? null,
pendingInvitationsCount: org.pending_invitations_count ?? null,
maxAllowedMemberships: org.max_allowed_memberships ?? 0,
adminDeleteEnabled: org.admin_delete_enabled ?? false,
createdBy: org.created_by ?? null,
createdAt: org.created_at,
updatedAt: org.updated_at,
publicMetadata: org.public_metadata ?? {},
}))
return {
success: true,
output: {
organizations,
totalCount: responseData.total_count ?? organizations.length,
success: true,
},
}
},
outputs: {
organizations: {
type: 'array',
description: 'Array of Clerk organization objects',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Organization ID' },
name: { type: 'string', description: 'Organization name' },
slug: { type: 'string', description: 'Organization slug', optional: true },
imageUrl: { type: 'string', description: 'Organization image URL', optional: true },
hasImage: { type: 'boolean', description: 'Whether organization has an image' },
membersCount: { type: 'number', description: 'Number of members', optional: true },
pendingInvitationsCount: {
type: 'number',
description: 'Number of pending invitations',
optional: true,
},
maxAllowedMemberships: { type: 'number', description: 'Max allowed memberships' },
adminDeleteEnabled: { type: 'boolean', description: 'Whether admin delete is enabled' },
createdBy: { type: 'string', description: 'Creator user ID', optional: true },
createdAt: { type: 'number', description: 'Creation timestamp' },
updatedAt: { type: 'number', description: 'Last update timestamp' },
publicMetadata: { type: 'json', description: 'Public metadata' },
},
},
},
totalCount: { type: 'number', description: 'Total number of organizations' },
success: { type: 'boolean', description: 'Operation success status' },
},
}

View File

@@ -0,0 +1,152 @@
import { createLogger } from '@sim/logger'
import type {
ClerkApiError,
ClerkListSessionsParams,
ClerkListSessionsResponse,
ClerkSession,
} from '@/tools/clerk/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('ClerkListSessions')
export const clerkListSessionsTool: ToolConfig<ClerkListSessionsParams, ClerkListSessionsResponse> =
{
id: 'clerk_list_sessions',
name: 'List Sessions from Clerk',
description: 'List sessions for a user or client in your Clerk application',
version: '1.0.0',
params: {
secretKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'The Clerk Secret Key for API authentication',
},
userId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'User ID to list sessions for (required if clientId not provided)',
},
clientId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Client ID to list sessions for (required if userId not provided)',
},
status: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Filter by session status (abandoned, active, ended, expired, pending, removed, replaced, revoked)',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of results per page (1-500, default: 10)',
},
offset: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of results to skip for pagination',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.userId) queryParams.append('user_id', params.userId)
if (params.clientId) queryParams.append('client_id', params.clientId)
if (params.status) queryParams.append('status', params.status)
if (params.limit) queryParams.append('limit', params.limit.toString())
if (params.offset) queryParams.append('offset', params.offset.toString())
const queryString = queryParams.toString()
return queryString
? `https://api.clerk.com/v1/sessions?${queryString}`
: 'https://api.clerk.com/v1/sessions'
},
method: 'GET',
headers: (params) => {
if (!params.secretKey) {
throw new Error('Clerk Secret Key is required')
}
return {
Authorization: `Bearer ${params.secretKey}`,
'Content-Type': 'application/json',
}
},
},
transformResponse: async (response: Response) => {
const data: ClerkSession[] | ClerkApiError = await response.json()
if (!response.ok) {
logger.error('Clerk API request failed', { data, status: response.status })
throw new Error(
(data as ClerkApiError).errors?.[0]?.message || 'Failed to list sessions from Clerk'
)
}
const totalCount = Number.parseInt(response.headers.get('x-total-count') || '0', 10)
const sessions = (data as ClerkSession[]).map((session) => ({
id: session.id,
userId: session.user_id,
clientId: session.client_id,
status: session.status,
lastActiveAt: session.last_active_at ?? null,
lastActiveOrganizationId: session.last_active_organization_id ?? null,
expireAt: session.expire_at ?? null,
abandonAt: session.abandon_at ?? null,
createdAt: session.created_at,
updatedAt: session.updated_at,
}))
return {
success: true,
output: {
sessions,
totalCount: totalCount || sessions.length,
success: true,
},
}
},
outputs: {
sessions: {
type: 'array',
description: 'Array of Clerk session objects',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Session ID' },
userId: { type: 'string', description: 'User ID' },
clientId: { type: 'string', description: 'Client ID' },
status: { type: 'string', description: 'Session status' },
lastActiveAt: {
type: 'number',
description: 'Last activity timestamp',
optional: true,
},
lastActiveOrganizationId: {
type: 'string',
description: 'Last active organization ID',
optional: true,
},
expireAt: { type: 'number', description: 'Expiration timestamp', optional: true },
abandonAt: { type: 'number', description: 'Abandon timestamp', optional: true },
createdAt: { type: 'number', description: 'Creation timestamp' },
updatedAt: { type: 'number', description: 'Last update timestamp' },
},
},
},
totalCount: { type: 'number', description: 'Total number of sessions' },
success: { type: 'boolean', description: 'Operation success status' },
},
}

View File

@@ -0,0 +1,250 @@
import { createLogger } from '@sim/logger'
import type {
ClerkApiError,
ClerkEmailAddress,
ClerkListUsersParams,
ClerkListUsersResponse,
ClerkPhoneNumber,
ClerkUser,
} from '@/tools/clerk/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('ClerkListUsers')
export const clerkListUsersTool: ToolConfig<ClerkListUsersParams, ClerkListUsersResponse> = {
id: 'clerk_list_users',
name: 'List Users from Clerk',
description: 'List all users in your Clerk application with optional filtering and pagination',
version: '1.0.0',
params: {
secretKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'The Clerk Secret Key for API authentication',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of results per page (1-500, default: 10)',
},
offset: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of results to skip for pagination',
},
orderBy: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Sort field with optional +/- prefix for direction (default: -created_at)',
},
emailAddress: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by email address (comma-separated for multiple)',
},
phoneNumber: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by phone number (comma-separated for multiple)',
},
externalId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by external ID (comma-separated for multiple)',
},
username: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by username (comma-separated for multiple)',
},
userId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by user ID (comma-separated for multiple)',
},
query: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Search query to match across email, phone, username, and names',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.limit) queryParams.append('limit', params.limit.toString())
if (params.offset) queryParams.append('offset', params.offset.toString())
if (params.orderBy) queryParams.append('order_by', params.orderBy)
if (params.query) queryParams.append('query', params.query)
// Handle comma-separated array params
if (params.emailAddress) {
params.emailAddress.split(',').forEach((email) => {
queryParams.append('email_address', email.trim())
})
}
if (params.phoneNumber) {
params.phoneNumber.split(',').forEach((phone) => {
queryParams.append('phone_number', phone.trim())
})
}
if (params.externalId) {
params.externalId.split(',').forEach((id) => {
queryParams.append('external_id', id.trim())
})
}
if (params.username) {
params.username.split(',').forEach((uname) => {
queryParams.append('username', uname.trim())
})
}
if (params.userId) {
params.userId.split(',').forEach((id) => {
queryParams.append('user_id', id.trim())
})
}
const queryString = queryParams.toString()
return queryString
? `https://api.clerk.com/v1/users?${queryString}`
: 'https://api.clerk.com/v1/users'
},
method: 'GET',
headers: (params) => {
if (!params.secretKey) {
throw new Error('Clerk Secret Key is required')
}
return {
Authorization: `Bearer ${params.secretKey}`,
'Content-Type': 'application/json',
}
},
},
transformResponse: async (response: Response) => {
const data: ClerkUser[] | ClerkApiError = await response.json()
if (!response.ok) {
logger.error('Clerk API request failed', { data, status: response.status })
throw new Error(
(data as ClerkApiError).errors?.[0]?.message || 'Failed to list users from Clerk'
)
}
// The response is an array of users, total_count is in the header
const totalCount = Number.parseInt(response.headers.get('x-total-count') || '0', 10)
// Transform each user to extract key fields
const users = (data as ClerkUser[]).map((user) => ({
id: user.id,
username: user.username ?? null,
firstName: user.first_name ?? null,
lastName: user.last_name ?? null,
imageUrl: user.image_url ?? null,
hasImage: user.has_image ?? false,
primaryEmailAddressId: user.primary_email_address_id ?? null,
primaryPhoneNumberId: user.primary_phone_number_id ?? null,
emailAddresses: (user.email_addresses ?? []).map((email: ClerkEmailAddress) => ({
id: email.id,
emailAddress: email.email_address,
})),
phoneNumbers: (user.phone_numbers ?? []).map((phone: ClerkPhoneNumber) => ({
id: phone.id,
phoneNumber: phone.phone_number,
})),
externalId: user.external_id ?? null,
passwordEnabled: user.password_enabled ?? false,
twoFactorEnabled: user.two_factor_enabled ?? false,
banned: user.banned ?? false,
locked: user.locked ?? false,
lastSignInAt: user.last_sign_in_at ?? null,
lastActiveAt: user.last_active_at ?? null,
createdAt: user.created_at,
updatedAt: user.updated_at,
publicMetadata: user.public_metadata ?? {},
}))
return {
success: true,
output: {
users,
totalCount: totalCount || users.length,
success: true,
},
}
},
outputs: {
users: {
type: 'array',
description: 'Array of Clerk user objects',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'User ID' },
username: { type: 'string', description: 'Username', optional: true },
firstName: { type: 'string', description: 'First name', optional: true },
lastName: { type: 'string', description: 'Last name', optional: true },
imageUrl: { type: 'string', description: 'Profile image URL', optional: true },
hasImage: { type: 'boolean', description: 'Whether user has a profile image' },
primaryEmailAddressId: {
type: 'string',
description: 'Primary email address ID',
optional: true,
},
primaryPhoneNumberId: {
type: 'string',
description: 'Primary phone number ID',
optional: true,
},
emailAddresses: {
type: 'array',
description: 'User email addresses',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Email address ID' },
emailAddress: { type: 'string', description: 'Email address' },
},
},
},
phoneNumbers: {
type: 'array',
description: 'User phone numbers',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Phone number ID' },
phoneNumber: { type: 'string', description: 'Phone number' },
},
},
},
externalId: { type: 'string', description: 'External system ID', optional: true },
passwordEnabled: { type: 'boolean', description: 'Whether password is enabled' },
twoFactorEnabled: { type: 'boolean', description: 'Whether 2FA is enabled' },
banned: { type: 'boolean', description: 'Whether user is banned' },
locked: { type: 'boolean', description: 'Whether user is locked' },
lastSignInAt: { type: 'number', description: 'Last sign-in timestamp', optional: true },
lastActiveAt: { type: 'number', description: 'Last activity timestamp', optional: true },
createdAt: { type: 'number', description: 'Creation timestamp' },
updatedAt: { type: 'number', description: 'Last update timestamp' },
publicMetadata: { type: 'json', description: 'Public metadata' },
},
},
},
totalCount: { type: 'number', description: 'Total number of users matching the query' },
success: { type: 'boolean', description: 'Operation success status' },
},
}

View File

@@ -0,0 +1,96 @@
import { createLogger } from '@sim/logger'
import type {
ClerkApiError,
ClerkRevokeSessionParams,
ClerkRevokeSessionResponse,
ClerkSession,
} from '@/tools/clerk/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('ClerkRevokeSession')
export const clerkRevokeSessionTool: ToolConfig<
ClerkRevokeSessionParams,
ClerkRevokeSessionResponse
> = {
id: 'clerk_revoke_session',
name: 'Revoke Session in Clerk',
description: 'Revoke a session to immediately invalidate it',
version: '1.0.0',
params: {
secretKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'The Clerk Secret Key for API authentication',
},
sessionId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the session to revoke',
},
},
request: {
url: (params) => `https://api.clerk.com/v1/sessions/${params.sessionId}/revoke`,
method: 'POST',
headers: (params) => {
if (!params.secretKey) {
throw new Error('Clerk Secret Key is required')
}
return {
Authorization: `Bearer ${params.secretKey}`,
'Content-Type': 'application/json',
}
},
},
transformResponse: async (response: Response) => {
const data: ClerkSession | ClerkApiError = await response.json()
if (!response.ok) {
logger.error('Clerk API request failed', { data, status: response.status })
throw new Error(
(data as ClerkApiError).errors?.[0]?.message || 'Failed to revoke session in Clerk'
)
}
const session = data as ClerkSession
return {
success: true,
output: {
id: session.id,
userId: session.user_id,
clientId: session.client_id,
status: session.status,
lastActiveAt: session.last_active_at ?? null,
lastActiveOrganizationId: session.last_active_organization_id ?? null,
expireAt: session.expire_at ?? null,
abandonAt: session.abandon_at ?? null,
createdAt: session.created_at,
updatedAt: session.updated_at,
success: true,
},
}
},
outputs: {
id: { type: 'string', description: 'Session ID' },
userId: { type: 'string', description: 'User ID' },
clientId: { type: 'string', description: 'Client ID' },
status: { type: 'string', description: 'Session status (should be revoked)' },
lastActiveAt: { type: 'number', description: 'Last activity timestamp', optional: true },
lastActiveOrganizationId: {
type: 'string',
description: 'Last active organization ID',
optional: true,
},
expireAt: { type: 'number', description: 'Expiration timestamp', optional: true },
abandonAt: { type: 'number', description: 'Abandon timestamp', optional: true },
createdAt: { type: 'number', description: 'Creation timestamp' },
updatedAt: { type: 'number', description: 'Last update timestamp' },
success: { type: 'boolean', description: 'Operation success status' },
},
}

View File

@@ -0,0 +1,552 @@
import type { ToolResponse } from '@/tools/types'
/**
* Clerk API error response
*/
export interface ClerkApiError {
errors?: { message: string }[]
}
/**
* Clerk delete response
*/
export interface ClerkDeleteResponse {
id: string
object: string
deleted: boolean
}
/**
* Clerk User object
*/
export interface ClerkUser {
id: string
object: 'user'
username: string | null
first_name: string | null
last_name: string | null
image_url: string
has_image: boolean
primary_email_address_id: string | null
primary_phone_number_id: string | null
primary_web3_wallet_id: string | null
password_enabled: boolean
two_factor_enabled: boolean
totp_enabled: boolean
backup_code_enabled: boolean
email_addresses: ClerkEmailAddress[]
phone_numbers: ClerkPhoneNumber[]
web3_wallets: ClerkWeb3Wallet[]
external_accounts: ClerkExternalAccount[]
external_id: string | null
last_sign_in_at: number | null
banned: boolean
locked: boolean
lockout_expires_in_seconds: number | null
verification_attempts_remaining: number | null
created_at: number
updated_at: number
delete_self_enabled: boolean
create_organization_enabled: boolean
last_active_at: number | null
profile_image_url: string
public_metadata: Record<string, unknown>
private_metadata: Record<string, unknown>
unsafe_metadata: Record<string, unknown>
}
export interface ClerkEmailAddress {
id: string
object: 'email_address'
email_address: string
verification: ClerkVerification | null
linked_to: ClerkLinkedIdentifier[]
created_at: number
updated_at: number
}
export interface ClerkPhoneNumber {
id: string
object: 'phone_number'
phone_number: string
reserved_for_second_factor: boolean
default_second_factor: boolean
verification: ClerkVerification | null
linked_to: ClerkLinkedIdentifier[]
backup_codes: string[] | null
created_at: number
updated_at: number
}
export interface ClerkWeb3Wallet {
id: string
object: 'web3_wallet'
web3_wallet: string
verification: ClerkVerification | null
created_at: number
updated_at: number
}
export interface ClerkExternalAccount {
id: string
object: 'external_account'
provider: string
identification_id: string
provider_user_id: string
approved_scopes: string
email_address: string
first_name: string
last_name: string
image_url: string
username: string | null
public_metadata: Record<string, unknown>
label: string | null
verification: ClerkVerification | null
created_at: number
updated_at: number
}
export interface ClerkVerification {
status: string
strategy: string
attempts: number | null
expire_at: number | null
}
export interface ClerkLinkedIdentifier {
type: string
id: string
}
/**
* Clerk Organization object
*/
export interface ClerkOrganization {
id: string
object: 'organization'
name: string
slug: string
image_url: string
has_image: boolean
members_count?: number
pending_invitations_count?: number
max_allowed_memberships: number
admin_delete_enabled: boolean
public_metadata: Record<string, unknown>
private_metadata: Record<string, unknown>
created_by: string
created_at: number
updated_at: number
}
/**
* Clerk Session object
*/
export interface ClerkSession {
id: string
object: 'session'
user_id: string
client_id: string
actor: Record<string, unknown> | null
status:
| 'abandoned'
| 'active'
| 'ended'
| 'expired'
| 'pending'
| 'removed'
| 'replaced'
| 'revoked'
last_active_organization_id: string | null
last_active_at: number
expire_at: number
abandon_at: number
created_at: number
updated_at: number
}
/**
* Transformed email address for outputs
*/
export interface ClerkEmailAddressOutput {
id: string
emailAddress: string
verified?: boolean
}
/**
* Transformed phone number for outputs
*/
export interface ClerkPhoneNumberOutput {
id: string
phoneNumber: string
verified?: boolean
}
/**
* Transformed user for list outputs
*/
export interface ClerkUserOutput {
id: string
username: string | null
firstName: string | null
lastName: string | null
imageUrl: string | null
hasImage: boolean
primaryEmailAddressId: string | null
primaryPhoneNumberId: string | null
emailAddresses: ClerkEmailAddressOutput[]
phoneNumbers: ClerkPhoneNumberOutput[]
externalId: string | null
passwordEnabled: boolean
twoFactorEnabled: boolean
banned: boolean
locked: boolean
lastSignInAt: number | null
lastActiveAt: number | null
createdAt: number
updatedAt: number
publicMetadata: Record<string, unknown>
}
/**
* Transformed organization for outputs
*/
export interface ClerkOrganizationOutput {
id: string
name: string
slug: string | null
imageUrl: string | null
hasImage: boolean
membersCount: number | null
pendingInvitationsCount: number | null
maxAllowedMemberships: number
adminDeleteEnabled: boolean
createdBy: string | null
createdAt: number
updatedAt: number
publicMetadata: Record<string, unknown>
}
/**
* Transformed session for outputs
*/
export interface ClerkSessionOutput {
id: string
userId: string
clientId: string
status: string
lastActiveAt: number | null
lastActiveOrganizationId: string | null
expireAt: number | null
abandonAt: number | null
createdAt: number
updatedAt: number
}
// List Users
export interface ClerkListUsersParams {
secretKey: string
limit?: number
offset?: number
orderBy?: string
emailAddress?: string
phoneNumber?: string
externalId?: string
username?: string
userId?: string
query?: string
}
export interface ClerkListUsersResponse extends ToolResponse {
output: {
users: ClerkUserOutput[]
totalCount: number
success: boolean
}
}
// Get User
export interface ClerkGetUserParams {
secretKey: string
userId: string
}
export interface ClerkGetUserResponse extends ToolResponse {
output: {
id: string
username: string | null
firstName: string | null
lastName: string | null
imageUrl: string | null
hasImage: boolean
primaryEmailAddressId: string | null
primaryPhoneNumberId: string | null
primaryWeb3WalletId: string | null
emailAddresses: ClerkEmailAddressOutput[]
phoneNumbers: ClerkPhoneNumberOutput[]
externalId: string | null
passwordEnabled: boolean
twoFactorEnabled: boolean
totpEnabled: boolean
backupCodeEnabled: boolean
banned: boolean
locked: boolean
deleteSelfEnabled: boolean
createOrganizationEnabled: boolean
lastSignInAt: number | null
lastActiveAt: number | null
createdAt: number
updatedAt: number
publicMetadata: Record<string, unknown>
privateMetadata: Record<string, unknown>
unsafeMetadata: Record<string, unknown>
success: boolean
}
}
// Create User
export interface ClerkCreateUserParams {
secretKey: string
emailAddress?: string | string[]
phoneNumber?: string | string[]
username?: string
password?: string
firstName?: string
lastName?: string
externalId?: string
publicMetadata?: Record<string, unknown>
privateMetadata?: Record<string, unknown>
unsafeMetadata?: Record<string, unknown>
skipPasswordChecks?: boolean
skipPasswordRequirement?: boolean
}
export interface ClerkCreateUserResponse extends ToolResponse {
output: {
id: string
username: string | null
firstName: string | null
lastName: string | null
imageUrl: string | null
primaryEmailAddressId: string | null
primaryPhoneNumberId: string | null
emailAddresses: ClerkEmailAddressOutput[]
phoneNumbers: ClerkPhoneNumberOutput[]
externalId: string | null
createdAt: number
updatedAt: number
publicMetadata: Record<string, unknown>
success: boolean
}
}
// Update User
export interface ClerkUpdateUserParams {
secretKey: string
userId: string
firstName?: string
lastName?: string
username?: string
password?: string
externalId?: string
primaryEmailAddressId?: string
primaryPhoneNumberId?: string
publicMetadata?: Record<string, unknown>
privateMetadata?: Record<string, unknown>
unsafeMetadata?: Record<string, unknown>
skipPasswordChecks?: boolean
}
export interface ClerkUpdateUserResponse extends ToolResponse {
output: {
id: string
username: string | null
firstName: string | null
lastName: string | null
imageUrl: string | null
primaryEmailAddressId: string | null
primaryPhoneNumberId: string | null
emailAddresses: ClerkEmailAddressOutput[]
phoneNumbers: ClerkPhoneNumberOutput[]
externalId: string | null
banned: boolean
locked: boolean
createdAt: number
updatedAt: number
publicMetadata: Record<string, unknown>
success: boolean
}
}
// Delete User
export interface ClerkDeleteUserParams {
secretKey: string
userId: string
}
export interface ClerkDeleteUserResponse extends ToolResponse {
output: {
id: string
object: string
deleted: boolean
success: boolean
}
}
// List Organizations
export interface ClerkListOrganizationsParams {
secretKey: string
limit?: number
offset?: number
includeMembersCount?: boolean
query?: string
orderBy?: string
}
export interface ClerkListOrganizationsResponse extends ToolResponse {
output: {
organizations: ClerkOrganizationOutput[]
totalCount: number
success: boolean
}
}
// Get Organization
export interface ClerkGetOrganizationParams {
secretKey: string
organizationId: string
}
export interface ClerkGetOrganizationResponse extends ToolResponse {
output: {
id: string
name: string
slug: string | null
imageUrl: string | null
hasImage: boolean
membersCount: number | null
pendingInvitationsCount: number | null
maxAllowedMemberships: number
adminDeleteEnabled: boolean
createdBy: string | null
createdAt: number
updatedAt: number
publicMetadata: Record<string, unknown>
success: boolean
}
}
// Create Organization
export interface ClerkCreateOrganizationParams {
secretKey: string
name: string
createdBy: string
slug?: string
maxAllowedMemberships?: number
publicMetadata?: Record<string, unknown>
privateMetadata?: Record<string, unknown>
}
export interface ClerkCreateOrganizationResponse extends ToolResponse {
output: {
id: string
name: string
slug: string | null
imageUrl: string | null
hasImage: boolean
membersCount: number | null
pendingInvitationsCount: number | null
maxAllowedMemberships: number
adminDeleteEnabled: boolean
createdBy: string | null
createdAt: number
updatedAt: number
publicMetadata: Record<string, unknown>
success: boolean
}
}
// List Sessions
export interface ClerkListSessionsParams {
secretKey: string
userId?: string
clientId?: string
status?:
| 'abandoned'
| 'active'
| 'ended'
| 'expired'
| 'pending'
| 'removed'
| 'replaced'
| 'revoked'
limit?: number
offset?: number
}
export interface ClerkListSessionsResponse extends ToolResponse {
output: {
sessions: ClerkSessionOutput[]
totalCount: number
success: boolean
}
}
// Get Session
export interface ClerkGetSessionParams {
secretKey: string
sessionId: string
}
export interface ClerkGetSessionResponse extends ToolResponse {
output: {
id: string
userId: string
clientId: string
status: string
lastActiveAt: number | null
lastActiveOrganizationId: string | null
expireAt: number | null
abandonAt: number | null
createdAt: number
updatedAt: number
success: boolean
}
}
// Revoke Session
export interface ClerkRevokeSessionParams {
secretKey: string
sessionId: string
}
export interface ClerkRevokeSessionResponse extends ToolResponse {
output: {
id: string
userId: string
clientId: string
status: string
lastActiveAt: number | null
lastActiveOrganizationId: string | null
expireAt: number | null
abandonAt: number | null
createdAt: number
updatedAt: number
success: boolean
}
}
// Generic response type for the block
export type ClerkResponse =
| ClerkListUsersResponse
| ClerkGetUserResponse
| ClerkCreateUserResponse
| ClerkUpdateUserResponse
| ClerkDeleteUserResponse
| ClerkListOrganizationsResponse
| ClerkGetOrganizationResponse
| ClerkCreateOrganizationResponse
| ClerkListSessionsResponse
| ClerkGetSessionResponse
| ClerkRevokeSessionResponse

View File

@@ -0,0 +1,225 @@
import { createLogger } from '@sim/logger'
import type {
ClerkApiError,
ClerkEmailAddress,
ClerkPhoneNumber,
ClerkUpdateUserParams,
ClerkUpdateUserResponse,
ClerkUser,
} from '@/tools/clerk/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('ClerkUpdateUser')
export const clerkUpdateUserTool: ToolConfig<ClerkUpdateUserParams, ClerkUpdateUserResponse> = {
id: 'clerk_update_user',
name: 'Update User in Clerk',
description: 'Update an existing user in your Clerk application',
version: '1.0.0',
params: {
secretKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'The Clerk Secret Key for API authentication',
},
userId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the user to update',
},
firstName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'First name of the user',
},
lastName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Last name of the user',
},
username: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Username (must be unique)',
},
password: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'New password (minimum 8 characters)',
},
externalId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'External system identifier',
},
primaryEmailAddressId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'ID of verified email to set as primary',
},
primaryPhoneNumberId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'ID of verified phone to set as primary',
},
publicMetadata: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Public metadata (JSON object)',
},
privateMetadata: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Private metadata (JSON object)',
},
unsafeMetadata: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Unsafe metadata (JSON object)',
},
skipPasswordChecks: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Skip password validation checks',
},
},
request: {
url: (params) => `https://api.clerk.com/v1/users/${params.userId?.trim()}`,
method: 'PATCH',
headers: (params) => {
if (!params.secretKey) {
throw new Error('Clerk Secret Key is required')
}
return {
Authorization: `Bearer ${params.secretKey}`,
'Content-Type': 'application/json',
}
},
body: (params) => {
const body: Record<string, unknown> = {}
if (params.firstName !== undefined) body.first_name = params.firstName?.trim()
if (params.lastName !== undefined) body.last_name = params.lastName?.trim()
if (params.username !== undefined) body.username = params.username?.trim()
if (params.password !== undefined) body.password = params.password
if (params.externalId !== undefined) body.external_id = params.externalId?.trim()
if (params.primaryEmailAddressId !== undefined)
body.primary_email_address_id = params.primaryEmailAddressId?.trim()
if (params.primaryPhoneNumberId !== undefined)
body.primary_phone_number_id = params.primaryPhoneNumberId?.trim()
if (params.publicMetadata !== undefined) body.public_metadata = params.publicMetadata
if (params.privateMetadata !== undefined) body.private_metadata = params.privateMetadata
if (params.unsafeMetadata !== undefined) body.unsafe_metadata = params.unsafeMetadata
if (params.skipPasswordChecks !== undefined)
body.skip_password_checks = params.skipPasswordChecks
return body
},
},
transformResponse: async (response: Response) => {
const data: ClerkUser | ClerkApiError = await response.json()
if (!response.ok) {
logger.error('Clerk API request failed', { data, status: response.status })
throw new Error(
(data as ClerkApiError).errors?.[0]?.message || 'Failed to update user in Clerk'
)
}
const user = data as ClerkUser
return {
success: true,
output: {
id: user.id,
username: user.username ?? null,
firstName: user.first_name ?? null,
lastName: user.last_name ?? null,
imageUrl: user.image_url ?? null,
primaryEmailAddressId: user.primary_email_address_id ?? null,
primaryPhoneNumberId: user.primary_phone_number_id ?? null,
emailAddresses: (user.email_addresses ?? []).map((email: ClerkEmailAddress) => ({
id: email.id,
emailAddress: email.email_address,
verified: email.verification?.status === 'verified',
})),
phoneNumbers: (user.phone_numbers ?? []).map((phone: ClerkPhoneNumber) => ({
id: phone.id,
phoneNumber: phone.phone_number,
verified: phone.verification?.status === 'verified',
})),
externalId: user.external_id ?? null,
banned: user.banned ?? false,
locked: user.locked ?? false,
createdAt: user.created_at,
updatedAt: user.updated_at,
publicMetadata: user.public_metadata ?? {},
success: true,
},
}
},
outputs: {
id: { type: 'string', description: 'Updated user ID' },
username: { type: 'string', description: 'Username', optional: true },
firstName: { type: 'string', description: 'First name', optional: true },
lastName: { type: 'string', description: 'Last name', optional: true },
imageUrl: { type: 'string', description: 'Profile image URL', optional: true },
primaryEmailAddressId: {
type: 'string',
description: 'Primary email address ID',
optional: true,
},
primaryPhoneNumberId: {
type: 'string',
description: 'Primary phone number ID',
optional: true,
},
emailAddresses: {
type: 'array',
description: 'User email addresses',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Email address ID' },
emailAddress: { type: 'string', description: 'Email address' },
verified: { type: 'boolean', description: 'Whether email is verified' },
},
},
},
phoneNumbers: {
type: 'array',
description: 'User phone numbers',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Phone number ID' },
phoneNumber: { type: 'string', description: 'Phone number' },
verified: { type: 'boolean', description: 'Whether phone is verified' },
},
},
},
externalId: { type: 'string', description: 'External system ID', optional: true },
banned: { type: 'boolean', description: 'Whether user is banned' },
locked: { type: 'boolean', description: 'Whether user is locked' },
createdAt: { type: 'number', description: 'Creation timestamp' },
updatedAt: { type: 'number', description: 'Last update timestamp' },
publicMetadata: { type: 'json', description: 'Public metadata' },
success: { type: 'boolean', description: 'Operation success status' },
},
}

View File

@@ -253,23 +253,6 @@ describe('executeTool Function', () => {
vi.restoreAllMocks() vi.restoreAllMocks()
}) })
it('should handle errors from tools', async () => {
setupFetchMock({ status: 400, ok: false, json: { error: 'Bad request' } })
const result = await executeTool(
'http_request',
{
url: 'https://api.example.com/data',
method: 'GET',
},
true
)
expect(result.success).toBe(false)
expect(result.error).toBeDefined()
expect(result.timing).toBeDefined()
})
it('should add timing information to results', async () => { it('should add timing information to results', async () => {
const result = await executeTool( const result = await executeTool(
'http_request', 'http_request',

View File

@@ -75,6 +75,19 @@ import {
calendlyListWebhooksTool, calendlyListWebhooksTool,
} from '@/tools/calendly' } from '@/tools/calendly'
import { clayPopulateTool } from '@/tools/clay' import { clayPopulateTool } from '@/tools/clay'
import {
clerkCreateOrganizationTool,
clerkCreateUserTool,
clerkDeleteUserTool,
clerkGetOrganizationTool,
clerkGetSessionTool,
clerkGetUserTool,
clerkListOrganizationsTool,
clerkListSessionsTool,
clerkListUsersTool,
clerkRevokeSessionTool,
clerkUpdateUserTool,
} from '@/tools/clerk'
import { import {
confluenceCreateCommentTool, confluenceCreateCommentTool,
confluenceCreatePageTool, confluenceCreatePageTool,
@@ -2571,6 +2584,17 @@ export const tools: Record<string, ToolConfig> = {
telegram_send_video: telegramSendVideoTool, telegram_send_video: telegramSendVideoTool,
telegram_send_document: telegramSendDocumentTool, telegram_send_document: telegramSendDocumentTool,
clay_populate: clayPopulateTool, clay_populate: clayPopulateTool,
clerk_list_users: clerkListUsersTool,
clerk_get_user: clerkGetUserTool,
clerk_create_user: clerkCreateUserTool,
clerk_update_user: clerkUpdateUserTool,
clerk_delete_user: clerkDeleteUserTool,
clerk_list_organizations: clerkListOrganizationsTool,
clerk_get_organization: clerkGetOrganizationTool,
clerk_create_organization: clerkCreateOrganizationTool,
clerk_list_sessions: clerkListSessionsTool,
clerk_get_session: clerkGetSessionTool,
clerk_revoke_session: clerkRevokeSessionTool,
discord_send_message: discordSendMessageTool, discord_send_message: discordSendMessageTool,
discord_get_messages: discordGetMessagesTool, discord_get_messages: discordGetMessagesTool,
discord_get_server: discordGetServerTool, discord_get_server: discordGetServerTool,

View File

@@ -0,0 +1,84 @@
{{- if .Values.certManager.enabled }}
{{- /*
cert-manager Issuer Bootstrap Pattern
PREREQUISITE: cert-manager must be installed in your cluster before enabling this.
The root CA Certificate is created in the namespace specified by certManager.rootCA.namespace
(defaults to "cert-manager"). Ensure this namespace exists and cert-manager is running there.
Install cert-manager: https://cert-manager.io/docs/installation/
This implements the recommended pattern from cert-manager documentation:
1. A self-signed ClusterIssuer (for bootstrapping the root CA only)
2. A root CA Certificate (self-signed, used to sign other certificates)
3. A CA ClusterIssuer (uses the root CA to sign certificates)
Reference: https://cert-manager.io/docs/configuration/selfsigned/
*/ -}}
---
# 1. Self-Signed ClusterIssuer (Bootstrap Only)
# This issuer is used ONLY to create the root CA certificate.
# It should NOT be used directly for application certificates.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: {{ .Values.certManager.selfSignedIssuer.name }}
labels:
{{- include "sim.labels" . | nindent 4 }}
app.kubernetes.io/component: cert-manager
spec:
selfSigned: {}
---
# 2. Root CA Certificate
# This certificate is signed by the self-signed issuer and becomes the root of trust.
# The secret created here will be used by the CA issuer to sign certificates.
# NOTE: This must be created in the cert-manager namespace (or the namespace specified
# in certManager.rootCA.namespace). Ensure cert-manager is installed there first.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: {{ .Values.certManager.rootCA.certificateName }}
namespace: {{ .Values.certManager.rootCA.namespace | default "cert-manager" }} # Must match cert-manager's cluster-resource-namespace
labels:
{{- include "sim.labels" . | nindent 4 }}
app.kubernetes.io/component: cert-manager
spec:
isCA: true
commonName: {{ .Values.certManager.rootCA.commonName }}
secretName: {{ .Values.certManager.rootCA.secretName }}
duration: {{ .Values.certManager.rootCA.duration | default "87600h" }}
renewBefore: {{ .Values.certManager.rootCA.renewBefore | default "2160h" }}
privateKey:
algorithm: {{ .Values.certManager.rootCA.privateKey.algorithm | default "RSA" }}
size: {{ .Values.certManager.rootCA.privateKey.size | default 4096 }}
subject:
organizations:
{{- if .Values.certManager.rootCA.subject.organizations }}
{{- toYaml .Values.certManager.rootCA.subject.organizations | nindent 6 }}
{{- else }}
- {{ .Release.Name }}
{{- end }}
issuerRef:
name: {{ .Values.certManager.selfSignedIssuer.name }}
kind: ClusterIssuer
group: cert-manager.io
---
# 3. CA ClusterIssuer
# This is the issuer that should be used by applications to obtain certificates.
# It signs certificates using the root CA created above.
# NOTE: This issuer may briefly show "not ready" on first install while cert-manager
# processes the Certificate above and creates the secret. It will auto-reconcile.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: {{ .Values.certManager.caIssuer.name }}
labels:
{{- include "sim.labels" . | nindent 4 }}
app.kubernetes.io/component: cert-manager
spec:
ca:
secretName: {{ .Values.certManager.rootCA.secretName }}
{{- end }}

View File

@@ -1,6 +1,36 @@
{{- if and .Values.ollama.enabled .Values.ollama.gpu.enabled }} {{- if and .Values.ollama.enabled .Values.ollama.gpu.enabled }}
--- ---
# NVIDIA Device Plugin DaemonSet for GPU support # 1. ConfigMap for NVIDIA Device Plugin Configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "sim.fullname" . }}-nvidia-device-plugin-config
namespace: {{ .Release.Namespace }}
labels:
{{- include "sim.labels" . | nindent 4 }}
app.kubernetes.io/component: nvidia-device-plugin
data:
config.yaml: |
version: v1
flags:
{{- if eq .Values.ollama.gpu.strategy "mig" }}
migStrategy: "single"
{{- else }}
migStrategy: "none"
{{- end }}
failOnInitError: false
plugin:
passDeviceSpecs: true
deviceListStrategy: envvar
{{- if eq .Values.ollama.gpu.strategy "time-slicing" }}
sharing:
timeSlicing:
resources:
- name: nvidia.com/gpu
replicas: {{ .Values.ollama.gpu.timeSlicingReplicas | default 5 }}
{{- end }}
---
# 2. NVIDIA Device Plugin DaemonSet for GPU support
apiVersion: apps/v1 apiVersion: apps/v1
kind: DaemonSet kind: DaemonSet
metadata: metadata:
@@ -35,9 +65,6 @@ spec:
# Only schedule on nodes with NVIDIA GPUs # Only schedule on nodes with NVIDIA GPUs
accelerator: nvidia accelerator: nvidia
priorityClassName: system-node-critical priorityClassName: system-node-critical
runtimeClassName: nvidia
hostNetwork: true
hostPID: true
volumes: volumes:
- name: device-plugin - name: device-plugin
hostPath: hostPath:
@@ -48,22 +75,21 @@ spec:
- name: sys - name: sys
hostPath: hostPath:
path: /sys path: /sys
- name: proc-driver-nvidia # Volume to mount the ConfigMap
hostPath: - name: nvidia-device-plugin-config
path: /proc/driver/nvidia configMap:
name: {{ include "sim.fullname" . }}-nvidia-device-plugin-config
containers: containers:
- name: nvidia-device-plugin - name: nvidia-device-plugin
image: nvcr.io/nvidia/k8s-device-plugin:v0.14.5 image: nvcr.io/nvidia/k8s-device-plugin:v0.18.2
imagePullPolicy: Always imagePullPolicy: Always
args: args:
- --mig-strategy=single - "--config-file=/etc/device-plugin/config.yaml"
- --pass-device-specs=true {{- if eq .Values.ollama.gpu.strategy "mig" }}
- --fail-on-init-error=false
- --device-list-strategy=envvar
- --nvidia-driver-root=/host-sys/fs/cgroup
env: env:
- name: NVIDIA_MIG_MONITOR_DEVICES - name: NVIDIA_MIG_MONITOR_DEVICES
value: all value: all
{{- end }}
securityContext: securityContext:
allowPrivilegeEscalation: false allowPrivilegeEscalation: false
capabilities: capabilities:
@@ -74,29 +100,16 @@ spec:
- name: dev - name: dev
mountPath: /dev mountPath: /dev
- name: sys - name: sys
mountPath: /host-sys mountPath: /sys
readOnly: true readOnly: true
- name: proc-driver-nvidia - name: nvidia-device-plugin-config
mountPath: /proc/driver/nvidia mountPath: /etc/device-plugin/
readOnly: true readOnly: true
resources: resources:
requests: requests:
cpu: 50m cpu: 50m
memory: 10Mi memory: 20Mi
limits: limits:
cpu: 50m cpu: 50m
memory: 20Mi memory: 50Mi
{{- if .Values.nodeSelector }} {{- end }}
nodeSelector:
{{- toYaml .Values.nodeSelector | nindent 8 }}
{{- end }}
---
# RuntimeClass for NVIDIA Container Runtime
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: {{ include "sim.fullname" . }}-nvidia
labels:
{{- include "sim.labels" . | nindent 4 }}
handler: nvidia
{{- end }}

View File

@@ -400,8 +400,10 @@ postgresql:
algorithm: RSA # RSA or ECDSA algorithm: RSA # RSA or ECDSA
size: 4096 # Key size in bits size: 4096 # Key size in bits
# Issuer reference (REQUIRED if tls.enabled is true) # Issuer reference (REQUIRED if tls.enabled is true)
# By default, references the CA issuer created by certManager.caIssuer
# Make sure certManager.enabled is true, or provide your own issuer
issuerRef: issuerRef:
name: selfsigned-cluster-issuer # Name of your cert-manager Issuer/ClusterIssuer name: sim-ca-issuer # Name of your cert-manager Issuer/ClusterIssuer
kind: ClusterIssuer # ClusterIssuer or Issuer kind: ClusterIssuer # ClusterIssuer or Issuer
group: "" # Optional: cert-manager.io (leave empty for default) group: "" # Optional: cert-manager.io (leave empty for default)
# Additional DNS names (optional) # Additional DNS names (optional)
@@ -463,20 +465,26 @@ externalDatabase:
ollama: ollama:
# Enable/disable Ollama deployment # Enable/disable Ollama deployment
enabled: false enabled: false
# Image configuration # Image configuration
image: image:
repository: ollama/ollama repository: ollama/ollama
tag: latest tag: latest
pullPolicy: Always pullPolicy: Always
# Number of replicas # Number of replicas
replicaCount: 1 replicaCount: 1
# GPU configuration # GPU configuration
gpu: gpu:
enabled: false enabled: false
count: 1 count: 1
# GPU sharing strategy: "mig" (Multi-Instance GPU) or "time-slicing"
# - mig: Hardware-level GPU partitioning (requires supported GPUs like A100)
# - time-slicing: Software-level GPU sharing (works with most NVIDIA GPUs)
strategy: "time-slicing"
# Number of time-slicing replicas (only used when strategy is "time-slicing")
timeSlicingReplicas: 5
# Node selector for GPU workloads (adjust labels based on your cluster configuration) # Node selector for GPU workloads (adjust labels based on your cluster configuration)
nodeSelector: nodeSelector:
@@ -1185,4 +1193,53 @@ externalSecrets:
# External database password (when using managed database services) # External database password (when using managed database services)
externalDatabase: externalDatabase:
# Path to external database password in external store # Path to external database password in external store
password: "" password: ""
# cert-manager configuration
# Prerequisites: Install cert-manager in your cluster first
# See: https://cert-manager.io/docs/installation/
#
# This implements the recommended CA bootstrap pattern from cert-manager:
# 1. Self-signed ClusterIssuer (bootstrap only - creates root CA)
# 2. Root CA Certificate (self-signed, becomes the trust anchor)
# 3. CA ClusterIssuer (signs application certificates using root CA)
#
# Reference: https://cert-manager.io/docs/configuration/selfsigned/
certManager:
# Enable/disable cert-manager issuer resources
enabled: false
# Self-signed ClusterIssuer (used ONLY to bootstrap the root CA)
# Do not reference this issuer directly for application certificates
selfSignedIssuer:
name: "sim-selfsigned-bootstrap-issuer"
# Root CA Certificate configuration
# This certificate is signed by the self-signed issuer and used as the trust anchor
rootCA:
# Name of the Certificate resource
certificateName: "sim-root-ca"
# Namespace where the root CA certificate and secret will be created
# Must match cert-manager's cluster-resource-namespace (default: cert-manager)
namespace: "cert-manager"
# Common name for the root CA certificate
commonName: "sim-root-ca"
# Secret name where the root CA certificate and key will be stored
secretName: "sim-root-ca-secret"
# Certificate validity duration (default: 10 years)
duration: "87600h"
# Renew before expiry (default: 90 days)
renewBefore: "2160h"
# Private key configuration
privateKey:
algorithm: RSA
size: 4096
# Subject configuration
subject:
organizations: []
# If empty, defaults to the release name
# CA ClusterIssuer configuration
# This is the issuer that applications should reference for obtaining certificates
caIssuer:
name: "sim-ca-issuer"

View File

@@ -1122,6 +1122,15 @@ function parsePropertiesContent(propertiesContent: string): Record<string, any>
continue continue
} }
// Check if this match is at depth 0 (not inside nested braces)
// Only process top-level properties, skip nested ones
const beforeMatch = propertiesContent.substring(0, match.index)
const openBraces = (beforeMatch.match(/{/g) || []).length
const closeBraces = (beforeMatch.match(/}/g) || []).length
if (openBraces !== closeBraces) {
continue // Skip - this is a nested property
}
const startPos = match.index + match[0].length - 1 const startPos = match.index + match[0].length - 1
let braceCount = 1 let braceCount = 1