mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-08 22:48:14 -05:00
fix(tools): fixed tool outputs (#2534)
* fixed typeform * fixed supabase tools * salesforce fix * removed comments * pinecone fix * fixed intercom * regex constant * removed fallback logic
This commit is contained in:
@@ -10,6 +10,8 @@ export const dynamic = 'force-dynamic'
|
||||
|
||||
const logger = createLogger('OAuthTokenAPI')
|
||||
|
||||
const SALESFORCE_INSTANCE_URL_REGEX = /__sf_instance__:([^\s]+)/
|
||||
|
||||
const tokenRequestSchema = z.object({
|
||||
credentialId: z
|
||||
.string({ required_error: 'Credential ID is required' })
|
||||
@@ -78,10 +80,20 @@ export async function POST(request: NextRequest) {
|
||||
try {
|
||||
// Refresh the token if needed
|
||||
const { accessToken } = await refreshTokenIfNeeded(requestId, credential, credentialId)
|
||||
|
||||
let instanceUrl: string | undefined
|
||||
if (credential.providerId === 'salesforce' && credential.scope) {
|
||||
const instanceMatch = credential.scope.match(SALESFORCE_INSTANCE_URL_REGEX)
|
||||
if (instanceMatch) {
|
||||
instanceUrl = instanceMatch[1]
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
accessToken,
|
||||
idToken: credential.idToken || undefined,
|
||||
...(instanceUrl && { instanceUrl }),
|
||||
},
|
||||
{ status: 200 }
|
||||
)
|
||||
@@ -147,10 +159,21 @@ export async function GET(request: NextRequest) {
|
||||
|
||||
try {
|
||||
const { accessToken } = await refreshTokenIfNeeded(requestId, credential, credentialId)
|
||||
|
||||
// For Salesforce, extract instanceUrl from the scope field
|
||||
let instanceUrl: string | undefined
|
||||
if (credential.providerId === 'salesforce' && credential.scope) {
|
||||
const instanceMatch = credential.scope.match(SALESFORCE_INSTANCE_URL_REGEX)
|
||||
if (instanceMatch) {
|
||||
instanceUrl = instanceMatch[1]
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
accessToken,
|
||||
idToken: credential.idToken || undefined,
|
||||
...(instanceUrl && { instanceUrl }),
|
||||
},
|
||||
{ status: 200 }
|
||||
)
|
||||
|
||||
@@ -264,7 +264,7 @@ export const PineconeBlock: BlockConfig<PineconeResponse> = {
|
||||
|
||||
outputs: {
|
||||
matches: { type: 'json', description: 'Search matches' },
|
||||
upsertedCount: { type: 'number', description: 'Upserted count' },
|
||||
statusText: { type: 'string', description: 'Status of the upsert operation' },
|
||||
data: { type: 'json', description: 'Response data' },
|
||||
model: { type: 'string', description: 'Model information' },
|
||||
vector_type: { type: 'string', description: 'Vector type' },
|
||||
|
||||
@@ -596,13 +596,20 @@ Return ONLY the PostgREST filter expression - no explanations, no markdown, no e
|
||||
},
|
||||
// Storage Upload fields
|
||||
{
|
||||
id: 'path',
|
||||
title: 'File Path',
|
||||
id: 'fileName',
|
||||
title: 'File Name',
|
||||
type: 'short-input',
|
||||
placeholder: 'folder/file.jpg',
|
||||
placeholder: 'myfile.pdf',
|
||||
condition: { field: 'operation', value: 'storage_upload' },
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
id: 'path',
|
||||
title: 'Folder Path (optional)',
|
||||
type: 'short-input',
|
||||
placeholder: 'folder/subfolder/',
|
||||
condition: { field: 'operation', value: 'storage_upload' },
|
||||
},
|
||||
{
|
||||
id: 'fileContent',
|
||||
title: 'File Content',
|
||||
@@ -1065,10 +1072,10 @@ Return ONLY the PostgREST filter expression - no explanations, no markdown, no e
|
||||
countType: { type: 'string', description: 'Count type: exact, planned, or estimated' },
|
||||
// Storage operation inputs
|
||||
bucket: { type: 'string', description: 'Storage bucket name' },
|
||||
path: { type: 'string', description: 'File path in storage' },
|
||||
path: { type: 'string', description: 'File or folder path in storage' },
|
||||
fileContent: { type: 'string', description: 'File content (base64 for binary)' },
|
||||
contentType: { type: 'string', description: 'MIME type of the file' },
|
||||
fileName: { type: 'string', description: 'Optional filename override for downloaded file' },
|
||||
fileName: { type: 'string', description: 'File name for upload or download override' },
|
||||
upsert: { type: 'boolean', description: 'Whether to overwrite existing file' },
|
||||
download: { type: 'boolean', description: 'Whether to force download' },
|
||||
paths: { type: 'array', description: 'Array of file paths' },
|
||||
|
||||
@@ -199,10 +199,76 @@ export const TypeformBlock: BlockConfig<TypeformResponse> = {
|
||||
{
|
||||
id: 'operations',
|
||||
title: 'JSON Patch Operations',
|
||||
type: 'long-input',
|
||||
placeholder: 'JSON array of patch operations (RFC 6902)',
|
||||
type: 'code',
|
||||
language: 'json',
|
||||
placeholder: '[{"op": "replace", "path": "/title", "value": "New Title"}]',
|
||||
condition: { field: 'operation', value: 'typeform_update_form' },
|
||||
required: true,
|
||||
wandConfig: {
|
||||
enabled: true,
|
||||
maintainHistory: true,
|
||||
prompt: `You are an expert at creating JSON Patch operations (RFC 6902) for Typeform forms.
|
||||
Generate ONLY the JSON array of patch operations based on the user's request.
|
||||
The output MUST be a valid JSON array, starting with [ and ending with ].
|
||||
|
||||
Current operations: {context}
|
||||
|
||||
### JSON PATCH OPERATIONS
|
||||
Each operation is an object with:
|
||||
- "op": The operation type ("add", "remove", "replace", "move", "copy", "test")
|
||||
- "path": JSON pointer to the target location (e.g., "/title", "/fields/0", "/settings/language")
|
||||
- "value": The new value (required for "add", "replace", "copy", "test")
|
||||
- "from": Source path (required for "move" and "copy")
|
||||
|
||||
### COMMON TYPEFORM PATHS
|
||||
- /title - Form title
|
||||
- /settings/language - Form language (e.g., "en", "es", "fr")
|
||||
- /settings/is_public - Whether form is public (true/false)
|
||||
- /settings/show_progress_bar - Show progress bar (true/false)
|
||||
- /fields - Array of form fields
|
||||
- /fields/- - Add to end of fields array
|
||||
- /fields/0 - First field
|
||||
- /welcome_screens - Array of welcome screens
|
||||
- /thankyou_screens - Array of thank you screens
|
||||
- /theme/href - Theme URL reference
|
||||
|
||||
### FIELD OBJECT STRUCTURE
|
||||
{
|
||||
"type": "short_text" | "long_text" | "email" | "number" | "multiple_choice" | "yes_no" | "rating" | "date" | "dropdown" | "file_upload",
|
||||
"title": "Question text",
|
||||
"ref": "unique_reference_id",
|
||||
"properties": { ... },
|
||||
"validations": { "required": true/false }
|
||||
}
|
||||
|
||||
### EXAMPLES
|
||||
|
||||
**Change form title:**
|
||||
[{"op": "replace", "path": "/title", "value": "My Updated Form"}]
|
||||
|
||||
**Add a new text field:**
|
||||
[{"op": "add", "path": "/fields/-", "value": {"type": "short_text", "title": "What is your name?", "ref": "name_field", "validations": {"required": true}}}]
|
||||
|
||||
**Add multiple choice field:**
|
||||
[{"op": "add", "path": "/fields/-", "value": {"type": "multiple_choice", "title": "Select your favorite color", "ref": "color_field", "properties": {"choices": [{"label": "Red"}, {"label": "Blue"}, {"label": "Green"}]}}}]
|
||||
|
||||
**Remove first field:**
|
||||
[{"op": "remove", "path": "/fields/0"}]
|
||||
|
||||
**Update form settings:**
|
||||
[{"op": "replace", "path": "/settings/language", "value": "es"}, {"op": "replace", "path": "/settings/is_public", "value": false}]
|
||||
|
||||
**Multiple operations:**
|
||||
[
|
||||
{"op": "replace", "path": "/title", "value": "Customer Feedback Form"},
|
||||
{"op": "add", "path": "/fields/-", "value": {"type": "rating", "title": "Rate your experience", "ref": "rating_field", "properties": {"steps": 5}}},
|
||||
{"op": "replace", "path": "/settings/show_progress_bar", "value": true}
|
||||
]
|
||||
|
||||
Do not include any explanations, markdown formatting, or other text outside the JSON array.`,
|
||||
placeholder: 'Describe how you want to update the form...',
|
||||
generationType: 'json-object',
|
||||
},
|
||||
},
|
||||
...getTrigger('typeform_webhook').subBlocks,
|
||||
],
|
||||
@@ -322,6 +388,9 @@ export const TypeformBlock: BlockConfig<TypeformResponse> = {
|
||||
fields: { type: 'json', description: 'Form fields array' },
|
||||
welcome_screens: { type: 'json', description: 'Welcome screens array' },
|
||||
thankyou_screens: { type: 'json', description: 'Thank you screens array' },
|
||||
created_at: { type: 'string', description: 'Form creation timestamp' },
|
||||
last_updated_at: { type: 'string', description: 'Form last update timestamp' },
|
||||
published_at: { type: 'string', description: 'Form publication timestamp' },
|
||||
_links: { type: 'json', description: 'Related resource links' },
|
||||
// Delete form outputs
|
||||
deleted: { type: 'boolean', description: 'Whether the form was deleted' },
|
||||
|
||||
@@ -120,6 +120,35 @@ export const auth = betterAuth({
|
||||
})
|
||||
|
||||
if (existing) {
|
||||
let scopeToStore = account.scope
|
||||
|
||||
if (account.providerId === 'salesforce' && account.accessToken) {
|
||||
try {
|
||||
const response = await fetch(
|
||||
'https://login.salesforce.com/services/oauth2/userinfo',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${account.accessToken}`,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json()
|
||||
|
||||
if (data.profile) {
|
||||
const match = data.profile.match(/^(https:\/\/[^/]+)/)
|
||||
if (match && match[1] !== 'https://login.salesforce.com') {
|
||||
const instanceUrl = match[1]
|
||||
scopeToStore = `__sf_instance__:${instanceUrl} ${account.scope}`
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch Salesforce instance URL', { error })
|
||||
}
|
||||
}
|
||||
|
||||
await db
|
||||
.update(schema.account)
|
||||
.set({
|
||||
@@ -129,7 +158,7 @@ export const auth = betterAuth({
|
||||
idToken: account.idToken,
|
||||
accessTokenExpiresAt: account.accessTokenExpiresAt,
|
||||
refreshTokenExpiresAt: account.refreshTokenExpiresAt,
|
||||
scope: account.scope,
|
||||
scope: scopeToStore,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(schema.account.id, existing.id))
|
||||
@@ -140,24 +169,45 @@ export const auth = betterAuth({
|
||||
return { data: account }
|
||||
},
|
||||
after: async (account) => {
|
||||
// Salesforce doesn't return expires_in in its token response (unlike other OAuth providers).
|
||||
// We set a default 2-hour expiration so token refresh logic works correctly.
|
||||
if (account.providerId === 'salesforce' && !account.accessTokenExpiresAt) {
|
||||
const twoHoursFromNow = new Date(Date.now() + 2 * 60 * 60 * 1000)
|
||||
try {
|
||||
await db
|
||||
.update(schema.account)
|
||||
.set({ accessTokenExpiresAt: twoHoursFromNow })
|
||||
.where(eq(schema.account.id, account.id))
|
||||
logger.info(
|
||||
'[databaseHooks.account.create.after] Set default expiration for Salesforce token',
|
||||
{ accountId: account.id, expiresAt: twoHoursFromNow }
|
||||
)
|
||||
} catch (error) {
|
||||
logger.error(
|
||||
'[databaseHooks.account.create.after] Failed to set Salesforce token expiration',
|
||||
{ accountId: account.id, error }
|
||||
)
|
||||
if (account.providerId === 'salesforce') {
|
||||
const updates: {
|
||||
accessTokenExpiresAt?: Date
|
||||
scope?: string
|
||||
} = {}
|
||||
|
||||
if (!account.accessTokenExpiresAt) {
|
||||
updates.accessTokenExpiresAt = new Date(Date.now() + 2 * 60 * 60 * 1000)
|
||||
}
|
||||
|
||||
if (account.accessToken) {
|
||||
try {
|
||||
const response = await fetch(
|
||||
'https://login.salesforce.com/services/oauth2/userinfo',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${account.accessToken}`,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json()
|
||||
|
||||
if (data.profile) {
|
||||
const match = data.profile.match(/^(https:\/\/[^/]+)/)
|
||||
if (match && match[1] !== 'https://login.salesforce.com') {
|
||||
const instanceUrl = match[1]
|
||||
updates.scope = `__sf_instance__:${instanceUrl} ${account.scope}`
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch Salesforce instance URL', { error })
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(updates).length > 0) {
|
||||
await db.update(schema.account).set(updates).where(eq(schema.account.id, account.id))
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -928,8 +978,6 @@ export const auth = betterAuth({
|
||||
redirectURI: `${getBaseUrl()}/api/auth/oauth2/callback/salesforce`,
|
||||
getUserInfo: async (tokens) => {
|
||||
try {
|
||||
logger.info('Fetching Salesforce user profile')
|
||||
|
||||
const response = await fetch(
|
||||
'https://login.salesforce.com/services/oauth2/userinfo',
|
||||
{
|
||||
|
||||
@@ -26,3 +26,318 @@ export const mockHttpResponses = {
|
||||
status: 401,
|
||||
},
|
||||
}
|
||||
|
||||
// Gmail Mock Data
|
||||
export const mockGmailResponses = {
|
||||
// List messages response
|
||||
messageList: {
|
||||
messages: [
|
||||
{ id: 'msg1', threadId: 'thread1' },
|
||||
{ id: 'msg2', threadId: 'thread2' },
|
||||
{ id: 'msg3', threadId: 'thread3' },
|
||||
],
|
||||
nextPageToken: 'token123',
|
||||
},
|
||||
|
||||
// Empty list response
|
||||
emptyList: {
|
||||
messages: [],
|
||||
resultSizeEstimate: 0,
|
||||
},
|
||||
|
||||
// Single message response
|
||||
singleMessage: {
|
||||
id: 'msg1',
|
||||
threadId: 'thread1',
|
||||
labelIds: ['INBOX', 'UNREAD'],
|
||||
snippet: 'This is a snippet preview of the email...',
|
||||
payload: {
|
||||
headers: [
|
||||
{ name: 'From', value: 'sender@example.com' },
|
||||
{ name: 'To', value: 'recipient@example.com' },
|
||||
{ name: 'Subject', value: 'Test Email Subject' },
|
||||
{ name: 'Date', value: 'Mon, 15 Mar 2025 10:30:00 -0800' },
|
||||
],
|
||||
mimeType: 'multipart/alternative',
|
||||
parts: [
|
||||
{
|
||||
mimeType: 'text/plain',
|
||||
body: {
|
||||
data: Buffer.from('This is the plain text content of the email').toString('base64'),
|
||||
},
|
||||
},
|
||||
{
|
||||
mimeType: 'text/html',
|
||||
body: {
|
||||
data: Buffer.from('<div>This is the HTML content of the email</div>').toString(
|
||||
'base64'
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Google Drive Mock Data
|
||||
export const mockDriveResponses = {
|
||||
// List files response
|
||||
fileList: {
|
||||
files: [
|
||||
{ id: 'file1', name: 'Document1.docx', mimeType: 'application/vnd.google-apps.document' },
|
||||
{
|
||||
id: 'file2',
|
||||
name: 'Spreadsheet.xlsx',
|
||||
mimeType: 'application/vnd.google-apps.spreadsheet',
|
||||
},
|
||||
{
|
||||
id: 'file3',
|
||||
name: 'Presentation.pptx',
|
||||
mimeType: 'application/vnd.google-apps.presentation',
|
||||
},
|
||||
],
|
||||
nextPageToken: 'drive-page-token',
|
||||
},
|
||||
|
||||
// Empty file list
|
||||
emptyFileList: {
|
||||
files: [],
|
||||
},
|
||||
|
||||
// Single file metadata
|
||||
fileMetadata: {
|
||||
id: 'file1',
|
||||
name: 'Document1.docx',
|
||||
mimeType: 'application/vnd.google-apps.document',
|
||||
webViewLink: 'https://docs.google.com/document/d/123/edit',
|
||||
createdTime: '2025-03-15T12:00:00Z',
|
||||
modifiedTime: '2025-03-16T10:15:00Z',
|
||||
owners: [{ displayName: 'Test User', emailAddress: 'user@example.com' }],
|
||||
size: '12345',
|
||||
},
|
||||
}
|
||||
|
||||
// Google Sheets Mock Data
|
||||
export const mockSheetsResponses = {
|
||||
// Read range response
|
||||
rangeData: {
|
||||
range: 'Sheet1!A1:D5',
|
||||
majorDimension: 'ROWS',
|
||||
values: [
|
||||
['Header1', 'Header2', 'Header3', 'Header4'],
|
||||
['Row1Col1', 'Row1Col2', 'Row1Col3', 'Row1Col4'],
|
||||
['Row2Col1', 'Row2Col2', 'Row2Col3', 'Row2Col4'],
|
||||
['Row3Col1', 'Row3Col2', 'Row3Col3', 'Row3Col4'],
|
||||
['Row4Col1', 'Row4Col2', 'Row4Col3', 'Row4Col4'],
|
||||
],
|
||||
},
|
||||
|
||||
// Empty range
|
||||
emptyRange: {
|
||||
range: 'Sheet1!A1:D5',
|
||||
majorDimension: 'ROWS',
|
||||
values: [],
|
||||
},
|
||||
|
||||
// Update range response
|
||||
updateResponse: {
|
||||
spreadsheetId: 'spreadsheet123',
|
||||
updatedRange: 'Sheet1!A1:D5',
|
||||
updatedRows: 5,
|
||||
updatedColumns: 4,
|
||||
updatedCells: 20,
|
||||
},
|
||||
}
|
||||
|
||||
// Pinecone Mock Data
|
||||
export const mockPineconeResponses = {
|
||||
// Vector embedding
|
||||
embedding: {
|
||||
embedding: Array(1536)
|
||||
.fill(0)
|
||||
.map(() => Math.random() * 2 - 1),
|
||||
metadata: { text: 'Sample text for embedding', id: 'embed-123' },
|
||||
},
|
||||
|
||||
// Search results
|
||||
searchResults: {
|
||||
matches: [
|
||||
{ id: 'doc1', score: 0.92, metadata: { text: 'Matching text 1' } },
|
||||
{ id: 'doc2', score: 0.85, metadata: { text: 'Matching text 2' } },
|
||||
{ id: 'doc3', score: 0.78, metadata: { text: 'Matching text 3' } },
|
||||
],
|
||||
},
|
||||
|
||||
// Upsert response
|
||||
upsertResponse: {
|
||||
statusText: 'Created',
|
||||
},
|
||||
}
|
||||
|
||||
// GitHub Mock Data
|
||||
export const mockGitHubResponses = {
|
||||
// Repository info
|
||||
repoInfo: {
|
||||
id: 12345,
|
||||
name: 'test-repo',
|
||||
full_name: 'user/test-repo',
|
||||
description: 'A test repository',
|
||||
html_url: 'https://github.com/user/test-repo',
|
||||
owner: {
|
||||
login: 'user',
|
||||
id: 54321,
|
||||
avatar_url: 'https://avatars.githubusercontent.com/u/54321',
|
||||
},
|
||||
private: false,
|
||||
fork: false,
|
||||
created_at: '2025-01-01T00:00:00Z',
|
||||
updated_at: '2025-03-15T10:00:00Z',
|
||||
pushed_at: '2025-03-15T09:00:00Z',
|
||||
default_branch: 'main',
|
||||
open_issues_count: 5,
|
||||
watchers_count: 10,
|
||||
forks_count: 3,
|
||||
stargazers_count: 15,
|
||||
language: 'TypeScript',
|
||||
},
|
||||
|
||||
// PR creation response
|
||||
prResponse: {
|
||||
id: 12345,
|
||||
number: 42,
|
||||
title: 'Test PR Title',
|
||||
body: 'Test PR description',
|
||||
html_url: 'https://github.com/user/test-repo/pull/42',
|
||||
state: 'open',
|
||||
user: {
|
||||
login: 'user',
|
||||
id: 54321,
|
||||
},
|
||||
created_at: '2025-03-15T10:00:00Z',
|
||||
updated_at: '2025-03-15T10:05:00Z',
|
||||
},
|
||||
}
|
||||
|
||||
// Serper Search Mock Data
|
||||
export const mockSerperResponses = {
|
||||
// Search results
|
||||
searchResults: {
|
||||
searchParameters: {
|
||||
q: 'test query',
|
||||
gl: 'us',
|
||||
hl: 'en',
|
||||
},
|
||||
organic: [
|
||||
{
|
||||
title: 'Test Result 1',
|
||||
link: 'https://example.com/1',
|
||||
snippet: 'This is a snippet for the first test result.',
|
||||
position: 1,
|
||||
},
|
||||
{
|
||||
title: 'Test Result 2',
|
||||
link: 'https://example.com/2',
|
||||
snippet: 'This is a snippet for the second test result.',
|
||||
position: 2,
|
||||
},
|
||||
{
|
||||
title: 'Test Result 3',
|
||||
link: 'https://example.com/3',
|
||||
snippet: 'This is a snippet for the third test result.',
|
||||
position: 3,
|
||||
},
|
||||
],
|
||||
knowledgeGraph: {
|
||||
title: 'Test Knowledge Graph',
|
||||
type: 'Test Type',
|
||||
description: 'This is a test knowledge graph result',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Slack Mock Data
|
||||
export const mockSlackResponses = {
|
||||
// Message post response
|
||||
messageResponse: {
|
||||
ok: true,
|
||||
channel: 'C1234567890',
|
||||
ts: '1627385301.000700',
|
||||
message: {
|
||||
text: 'This is a test message',
|
||||
user: 'U1234567890',
|
||||
ts: '1627385301.000700',
|
||||
team: 'T1234567890',
|
||||
},
|
||||
},
|
||||
|
||||
// Error response
|
||||
errorResponse: {
|
||||
ok: false,
|
||||
error: 'channel_not_found',
|
||||
},
|
||||
}
|
||||
|
||||
// Tavily Mock Data
|
||||
export const mockTavilyResponses = {
|
||||
// Search results
|
||||
searchResults: {
|
||||
results: [
|
||||
{
|
||||
title: 'Test Article 1',
|
||||
url: 'https://example.com/article1',
|
||||
content: 'This is the content of test article 1.',
|
||||
score: 0.95,
|
||||
},
|
||||
{
|
||||
title: 'Test Article 2',
|
||||
url: 'https://example.com/article2',
|
||||
content: 'This is the content of test article 2.',
|
||||
score: 0.87,
|
||||
},
|
||||
{
|
||||
title: 'Test Article 3',
|
||||
url: 'https://example.com/article3',
|
||||
content: 'This is the content of test article 3.',
|
||||
score: 0.72,
|
||||
},
|
||||
],
|
||||
query: 'test query',
|
||||
search_id: 'search-123',
|
||||
},
|
||||
}
|
||||
|
||||
// Supabase Mock Data
|
||||
export const mockSupabaseResponses = {
|
||||
// Query response
|
||||
queryResponse: {
|
||||
data: [
|
||||
{ id: 1, name: 'Item 1', description: 'Description 1' },
|
||||
{ id: 2, name: 'Item 2', description: 'Description 2' },
|
||||
{ id: 3, name: 'Item 3', description: 'Description 3' },
|
||||
],
|
||||
error: null,
|
||||
},
|
||||
|
||||
// Insert response
|
||||
insertResponse: {
|
||||
data: [{ id: 4, name: 'Item 4', description: 'Description 4' }],
|
||||
error: null,
|
||||
},
|
||||
|
||||
// Update response
|
||||
updateResponse: {
|
||||
data: [{ id: 1, name: 'Updated Item 1', description: 'Updated Description 1' }],
|
||||
error: null,
|
||||
},
|
||||
|
||||
// Error response
|
||||
errorResponse: {
|
||||
data: null,
|
||||
error: {
|
||||
message: 'Database error',
|
||||
details: 'Error details',
|
||||
hint: 'Error hint',
|
||||
code: 'DB_ERROR',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -305,10 +305,11 @@ export async function executeTool(
|
||||
if (data.idToken) {
|
||||
contextParams.idToken = data.idToken
|
||||
}
|
||||
if (data.instanceUrl) {
|
||||
contextParams.instanceUrl = data.instanceUrl
|
||||
}
|
||||
|
||||
logger.info(
|
||||
`[${requestId}] Successfully got access token for ${toolId}, length: ${data.accessToken?.length || 0}`
|
||||
)
|
||||
logger.info(`[${requestId}] Successfully got access token for ${toolId}`)
|
||||
|
||||
// Preserve credential for downstream transforms while removing it from request payload
|
||||
// so we don't leak it to external services.
|
||||
@@ -747,6 +748,8 @@ async function handleInternalRequest(
|
||||
url: fullUrl,
|
||||
json: () => response.json(),
|
||||
text: () => response.text(),
|
||||
arrayBuffer: () => response.arrayBuffer(),
|
||||
blob: () => response.blob(),
|
||||
} as Response
|
||||
|
||||
const data = await tool.transformResponse(mockResponse, params)
|
||||
|
||||
@@ -20,7 +20,33 @@ export interface IntercomCreateCompanyParams {
|
||||
export interface IntercomCreateCompanyResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
company: any
|
||||
company: {
|
||||
id: string
|
||||
type: string
|
||||
app_id: string
|
||||
company_id: string
|
||||
name?: string
|
||||
website?: string
|
||||
plan: Record<string, any>
|
||||
size?: number
|
||||
industry?: string
|
||||
monthly_spend: number
|
||||
session_count: number
|
||||
user_count: number
|
||||
created_at: number
|
||||
updated_at: number
|
||||
remote_created_at?: number
|
||||
custom_attributes: Record<string, any>
|
||||
tags: {
|
||||
type: string
|
||||
tags: any[]
|
||||
}
|
||||
segments: {
|
||||
type: string
|
||||
segments: any[]
|
||||
}
|
||||
[key: string]: any
|
||||
}
|
||||
metadata: {
|
||||
operation: 'create_company'
|
||||
companyId: string
|
||||
@@ -159,15 +185,55 @@ export const intercomCreateCompanyTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
company: {
|
||||
type: 'object',
|
||||
description: 'Created or updated company data',
|
||||
description: 'Created or updated company object',
|
||||
properties: {
|
||||
company: { type: 'object', description: 'Company object' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
id: { type: 'string', description: 'Unique identifier for the company' },
|
||||
type: { type: 'string', description: 'Object type (company)' },
|
||||
app_id: { type: 'string', description: 'Intercom app ID' },
|
||||
company_id: { type: 'string', description: 'Your unique identifier for the company' },
|
||||
name: { type: 'string', description: 'Name of the company' },
|
||||
website: { type: 'string', description: 'Company website URL' },
|
||||
plan: { type: 'object', description: 'Company plan information' },
|
||||
size: { type: 'number', description: 'Number of employees' },
|
||||
industry: { type: 'string', description: 'Industry the company operates in' },
|
||||
monthly_spend: { type: 'number', description: 'Monthly revenue from this company' },
|
||||
session_count: { type: 'number', description: 'Number of sessions' },
|
||||
user_count: { type: 'number', description: 'Number of users in the company' },
|
||||
created_at: { type: 'number', description: 'Unix timestamp when company was created' },
|
||||
updated_at: { type: 'number', description: 'Unix timestamp when company was last updated' },
|
||||
remote_created_at: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when company was created by you',
|
||||
},
|
||||
custom_attributes: { type: 'object', description: 'Custom attributes set on the company' },
|
||||
tags: {
|
||||
type: 'object',
|
||||
description: 'Tags associated with the company',
|
||||
properties: {
|
||||
type: { type: 'string', description: 'Tag list type' },
|
||||
tags: { type: 'array', description: 'Array of tag objects' },
|
||||
},
|
||||
},
|
||||
segments: {
|
||||
type: 'object',
|
||||
description: 'Segments the company belongs to',
|
||||
properties: {
|
||||
type: { type: 'string', description: 'Segment list type' },
|
||||
segments: { type: 'array', description: 'Array of segment objects' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (create_company)' },
|
||||
companyId: { type: 'string', description: 'ID of the created/updated company' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -23,7 +23,58 @@ export interface IntercomCreateContactParams {
|
||||
export interface IntercomCreateContactResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
contact: any
|
||||
contact: {
|
||||
id: string
|
||||
type: string
|
||||
role: string
|
||||
email: string | null
|
||||
phone: string | null
|
||||
name: string | null
|
||||
avatar: string | null
|
||||
owner_id: string | null
|
||||
external_id: string | null
|
||||
created_at: number
|
||||
updated_at: number
|
||||
signed_up_at: number | null
|
||||
last_seen_at: number | null
|
||||
workspace_id: string
|
||||
custom_attributes: Record<string, any>
|
||||
tags: {
|
||||
type: string
|
||||
url: string
|
||||
data: any[]
|
||||
has_more: boolean
|
||||
total_count: number
|
||||
}
|
||||
notes: {
|
||||
type: string
|
||||
url: string
|
||||
data: any[]
|
||||
has_more: boolean
|
||||
total_count: number
|
||||
}
|
||||
companies: {
|
||||
type: string
|
||||
url: string
|
||||
data: any[]
|
||||
has_more: boolean
|
||||
total_count: number
|
||||
}
|
||||
location: {
|
||||
type: string
|
||||
city: string | null
|
||||
region: string | null
|
||||
country: string | null
|
||||
country_code: string | null
|
||||
continent_code: string | null
|
||||
}
|
||||
social_profiles: {
|
||||
type: string
|
||||
data: any[]
|
||||
}
|
||||
unsubscribed_from_emails: boolean
|
||||
[key: string]: any
|
||||
}
|
||||
metadata: {
|
||||
operation: 'create_contact'
|
||||
contactId: string
|
||||
@@ -182,15 +233,92 @@ export const intercomCreateContactTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
contact: {
|
||||
type: 'object',
|
||||
description: 'Created contact data',
|
||||
description: 'Created contact object',
|
||||
properties: {
|
||||
contact: { type: 'object', description: 'Created contact object' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
id: { type: 'string', description: 'Unique identifier for the contact' },
|
||||
type: { type: 'string', description: 'Object type (contact)' },
|
||||
role: { type: 'string', description: 'Role of the contact (user or lead)' },
|
||||
email: { type: 'string', description: 'Email address of the contact' },
|
||||
phone: { type: 'string', description: 'Phone number of the contact' },
|
||||
name: { type: 'string', description: 'Name of the contact' },
|
||||
avatar: { type: 'string', description: 'Avatar URL of the contact' },
|
||||
owner_id: { type: 'string', description: 'ID of the admin assigned to this contact' },
|
||||
external_id: { type: 'string', description: 'External identifier for the contact' },
|
||||
created_at: { type: 'number', description: 'Unix timestamp when contact was created' },
|
||||
updated_at: { type: 'number', description: 'Unix timestamp when contact was last updated' },
|
||||
signed_up_at: { type: 'number', description: 'Unix timestamp when user signed up' },
|
||||
last_seen_at: { type: 'number', description: 'Unix timestamp when user was last seen' },
|
||||
workspace_id: { type: 'string', description: 'Workspace ID the contact belongs to' },
|
||||
custom_attributes: { type: 'object', description: 'Custom attributes set on the contact' },
|
||||
tags: {
|
||||
type: 'object',
|
||||
description: 'Tags associated with the contact',
|
||||
properties: {
|
||||
type: { type: 'string', description: 'List type' },
|
||||
url: { type: 'string', description: 'URL to fetch tags' },
|
||||
data: { type: 'array', description: 'Array of tag objects' },
|
||||
has_more: { type: 'boolean', description: 'Whether there are more tags' },
|
||||
total_count: { type: 'number', description: 'Total number of tags' },
|
||||
},
|
||||
},
|
||||
notes: {
|
||||
type: 'object',
|
||||
description: 'Notes associated with the contact',
|
||||
properties: {
|
||||
type: { type: 'string', description: 'List type' },
|
||||
url: { type: 'string', description: 'URL to fetch notes' },
|
||||
data: { type: 'array', description: 'Array of note objects' },
|
||||
has_more: { type: 'boolean', description: 'Whether there are more notes' },
|
||||
total_count: { type: 'number', description: 'Total number of notes' },
|
||||
},
|
||||
},
|
||||
companies: {
|
||||
type: 'object',
|
||||
description: 'Companies associated with the contact',
|
||||
properties: {
|
||||
type: { type: 'string', description: 'List type' },
|
||||
url: { type: 'string', description: 'URL to fetch companies' },
|
||||
data: { type: 'array', description: 'Array of company objects' },
|
||||
has_more: { type: 'boolean', description: 'Whether there are more companies' },
|
||||
total_count: { type: 'number', description: 'Total number of companies' },
|
||||
},
|
||||
},
|
||||
location: {
|
||||
type: 'object',
|
||||
description: 'Location information for the contact',
|
||||
properties: {
|
||||
type: { type: 'string', description: 'Location type' },
|
||||
city: { type: 'string', description: 'City' },
|
||||
region: { type: 'string', description: 'Region/State' },
|
||||
country: { type: 'string', description: 'Country' },
|
||||
country_code: { type: 'string', description: 'Country code' },
|
||||
continent_code: { type: 'string', description: 'Continent code' },
|
||||
},
|
||||
},
|
||||
social_profiles: {
|
||||
type: 'object',
|
||||
description: 'Social profiles of the contact',
|
||||
properties: {
|
||||
type: { type: 'string', description: 'List type' },
|
||||
data: { type: 'array', description: 'Array of social profile objects' },
|
||||
},
|
||||
},
|
||||
unsubscribed_from_emails: {
|
||||
type: 'boolean',
|
||||
description: 'Whether contact is unsubscribed from emails',
|
||||
},
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (create_contact)' },
|
||||
contactId: { type: 'string', description: 'ID of the created contact' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -161,15 +161,27 @@ export const intercomCreateMessageTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
message: {
|
||||
type: 'object',
|
||||
description: 'Created message data',
|
||||
description: 'Created message object',
|
||||
properties: {
|
||||
message: { type: 'object', description: 'Created message object' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
id: { type: 'string', description: 'Unique identifier for the message' },
|
||||
type: { type: 'string', description: 'Object type (message)' },
|
||||
created_at: { type: 'number', description: 'Unix timestamp when message was created' },
|
||||
body: { type: 'string', description: 'Body of the message' },
|
||||
message_type: { type: 'string', description: 'Type of the message (in_app or email)' },
|
||||
conversation_id: { type: 'string', description: 'ID of the conversation created' },
|
||||
owner: { type: 'object', description: 'Owner of the message' },
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (create_message)' },
|
||||
messageId: { type: 'string', description: 'ID of the created message' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -149,15 +149,41 @@ export const intercomCreateTicketTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
ticket: {
|
||||
type: 'object',
|
||||
description: 'Created ticket data',
|
||||
description: 'Created ticket object',
|
||||
properties: {
|
||||
ticket: { type: 'object', description: 'Created ticket object' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
id: { type: 'string', description: 'Unique identifier for the ticket' },
|
||||
type: { type: 'string', description: 'Object type (ticket)' },
|
||||
ticket_id: { type: 'string', description: 'Ticket ID' },
|
||||
ticket_type: { type: 'object', description: 'Type of the ticket' },
|
||||
ticket_attributes: { type: 'object', description: 'Attributes of the ticket' },
|
||||
ticket_state: { type: 'string', description: 'State of the ticket' },
|
||||
ticket_state_internal_label: {
|
||||
type: 'string',
|
||||
description: 'Internal label for ticket state',
|
||||
},
|
||||
ticket_state_external_label: {
|
||||
type: 'string',
|
||||
description: 'External label for ticket state',
|
||||
},
|
||||
created_at: { type: 'number', description: 'Unix timestamp when ticket was created' },
|
||||
updated_at: { type: 'number', description: 'Unix timestamp when ticket was last updated' },
|
||||
contacts: { type: 'object', description: 'Contacts associated with the ticket' },
|
||||
admin_assignee_id: { type: 'string', description: 'ID of assigned admin' },
|
||||
team_assignee_id: { type: 'string', description: 'ID of assigned team' },
|
||||
is_shared: { type: 'boolean', description: 'Whether the ticket is shared' },
|
||||
open: { type: 'boolean', description: 'Whether the ticket is open' },
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (create_ticket)' },
|
||||
ticketId: { type: 'string', description: 'ID of the created ticket' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -77,16 +77,15 @@ export const intercomDeleteContactTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
id: { type: 'string', description: 'ID of deleted contact' },
|
||||
deleted: { type: 'boolean', description: 'Whether the contact was deleted' },
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Deletion result',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'ID of deleted contact' },
|
||||
deleted: { type: 'boolean', description: 'Deletion status' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
operation: { type: 'string', description: 'The operation performed (delete_contact)' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -76,15 +76,36 @@ export const intercomGetCompanyTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
company: {
|
||||
type: 'object',
|
||||
description: 'Company data',
|
||||
description: 'Company object',
|
||||
properties: {
|
||||
company: { type: 'object', description: 'Company object' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
id: { type: 'string', description: 'Unique identifier for the company' },
|
||||
type: { type: 'string', description: 'Object type (company)' },
|
||||
app_id: { type: 'string', description: 'Intercom app ID' },
|
||||
company_id: { type: 'string', description: 'Your unique identifier for the company' },
|
||||
name: { type: 'string', description: 'Name of the company' },
|
||||
website: { type: 'string', description: 'Company website URL' },
|
||||
plan: { type: 'object', description: 'Company plan information' },
|
||||
size: { type: 'number', description: 'Number of employees' },
|
||||
industry: { type: 'string', description: 'Industry the company operates in' },
|
||||
monthly_spend: { type: 'number', description: 'Monthly revenue from this company' },
|
||||
session_count: { type: 'number', description: 'Number of sessions' },
|
||||
user_count: { type: 'number', description: 'Number of users in the company' },
|
||||
created_at: { type: 'number', description: 'Unix timestamp when company was created' },
|
||||
updated_at: { type: 'number', description: 'Unix timestamp when company was last updated' },
|
||||
custom_attributes: { type: 'object', description: 'Custom attributes set on the company' },
|
||||
tags: { type: 'object', description: 'Tags associated with the company' },
|
||||
segments: { type: 'object', description: 'Segments the company belongs to' },
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (get_company)' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -76,15 +76,41 @@ export const intercomGetContactTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
contact: {
|
||||
type: 'object',
|
||||
description: 'Contact data',
|
||||
description: 'Contact object',
|
||||
properties: {
|
||||
contact: { type: 'object', description: 'Contact object' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
id: { type: 'string', description: 'Unique identifier for the contact' },
|
||||
type: { type: 'string', description: 'Object type (contact)' },
|
||||
role: { type: 'string', description: 'Role of the contact (user or lead)' },
|
||||
email: { type: 'string', description: 'Email address of the contact' },
|
||||
phone: { type: 'string', description: 'Phone number of the contact' },
|
||||
name: { type: 'string', description: 'Name of the contact' },
|
||||
avatar: { type: 'string', description: 'Avatar URL of the contact' },
|
||||
owner_id: { type: 'string', description: 'ID of the admin assigned to this contact' },
|
||||
external_id: { type: 'string', description: 'External identifier for the contact' },
|
||||
created_at: { type: 'number', description: 'Unix timestamp when contact was created' },
|
||||
updated_at: { type: 'number', description: 'Unix timestamp when contact was last updated' },
|
||||
workspace_id: { type: 'string', description: 'Workspace ID the contact belongs to' },
|
||||
custom_attributes: { type: 'object', description: 'Custom attributes set on the contact' },
|
||||
tags: { type: 'object', description: 'Tags associated with the contact' },
|
||||
notes: { type: 'object', description: 'Notes associated with the contact' },
|
||||
companies: { type: 'object', description: 'Companies associated with the contact' },
|
||||
location: { type: 'object', description: 'Location information for the contact' },
|
||||
social_profiles: { type: 'object', description: 'Social profiles of the contact' },
|
||||
unsubscribed_from_emails: {
|
||||
type: 'boolean',
|
||||
description: 'Whether contact is unsubscribed from emails',
|
||||
},
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (get_contact)' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -101,15 +101,41 @@ export const intercomGetConversationTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
conversation: {
|
||||
type: 'object',
|
||||
description: 'Conversation data',
|
||||
description: 'Conversation object',
|
||||
properties: {
|
||||
conversation: { type: 'object', description: 'Conversation object' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
id: { type: 'string', description: 'Unique identifier for the conversation' },
|
||||
type: { type: 'string', description: 'Object type (conversation)' },
|
||||
title: { type: 'string', description: 'Title of the conversation' },
|
||||
created_at: { type: 'number', description: 'Unix timestamp when conversation was created' },
|
||||
updated_at: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when conversation was last updated',
|
||||
},
|
||||
waiting_since: { type: 'number', description: 'Unix timestamp when waiting for reply' },
|
||||
snoozed_until: { type: 'number', description: 'Unix timestamp when snooze ends' },
|
||||
open: { type: 'boolean', description: 'Whether the conversation is open' },
|
||||
state: { type: 'string', description: 'State of the conversation' },
|
||||
read: { type: 'boolean', description: 'Whether the conversation has been read' },
|
||||
priority: { type: 'string', description: 'Priority of the conversation' },
|
||||
admin_assignee_id: { type: 'number', description: 'ID of assigned admin' },
|
||||
team_assignee_id: { type: 'string', description: 'ID of assigned team' },
|
||||
tags: { type: 'object', description: 'Tags on the conversation' },
|
||||
source: { type: 'object', description: 'Source of the conversation' },
|
||||
contacts: { type: 'object', description: 'Contacts in the conversation' },
|
||||
teammates: { type: 'object', description: 'Teammates in the conversation' },
|
||||
conversation_parts: { type: 'object', description: 'Parts of the conversation' },
|
||||
statistics: { type: 'object', description: 'Conversation statistics' },
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (get_conversation)' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -74,15 +74,43 @@ export const intercomGetTicketTool: ToolConfig<IntercomGetTicketParams, Intercom
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
ticket: {
|
||||
type: 'object',
|
||||
description: 'Ticket data',
|
||||
description: 'Ticket object',
|
||||
properties: {
|
||||
ticket: { type: 'object', description: 'Ticket object' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
id: { type: 'string', description: 'Unique identifier for the ticket' },
|
||||
type: { type: 'string', description: 'Object type (ticket)' },
|
||||
ticket_id: { type: 'string', description: 'Ticket ID' },
|
||||
ticket_type: { type: 'object', description: 'Type of the ticket' },
|
||||
ticket_attributes: { type: 'object', description: 'Attributes of the ticket' },
|
||||
ticket_state: { type: 'string', description: 'State of the ticket' },
|
||||
ticket_state_internal_label: {
|
||||
type: 'string',
|
||||
description: 'Internal label for ticket state',
|
||||
},
|
||||
ticket_state_external_label: {
|
||||
type: 'string',
|
||||
description: 'External label for ticket state',
|
||||
},
|
||||
created_at: { type: 'number', description: 'Unix timestamp when ticket was created' },
|
||||
updated_at: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when ticket was last updated',
|
||||
},
|
||||
contacts: { type: 'object', description: 'Contacts associated with the ticket' },
|
||||
admin_assignee_id: { type: 'string', description: 'ID of assigned admin' },
|
||||
team_assignee_id: { type: 'string', description: 'ID of assigned team' },
|
||||
is_shared: { type: 'boolean', description: 'Whether the ticket is shared' },
|
||||
open: { type: 'boolean', description: 'Whether the ticket is open' },
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (get_ticket)' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -105,16 +105,54 @@ export const intercomListCompaniesTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
type: 'object',
|
||||
description: 'List of companies',
|
||||
properties: {
|
||||
companies: { type: 'array', description: 'Array of company objects' },
|
||||
pages: { type: 'object', description: 'Pagination information' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
companies: {
|
||||
type: 'array',
|
||||
description: 'Array of company objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the company' },
|
||||
type: { type: 'string', description: 'Object type (company)' },
|
||||
app_id: { type: 'string', description: 'Intercom app ID' },
|
||||
company_id: { type: 'string', description: 'Your unique identifier for the company' },
|
||||
name: { type: 'string', description: 'Name of the company' },
|
||||
website: { type: 'string', description: 'Company website URL' },
|
||||
plan: { type: 'object', description: 'Company plan information' },
|
||||
monthly_spend: { type: 'number', description: 'Monthly revenue from this company' },
|
||||
session_count: { type: 'number', description: 'Number of sessions' },
|
||||
user_count: { type: 'number', description: 'Number of users in the company' },
|
||||
created_at: { type: 'number', description: 'Unix timestamp when company was created' },
|
||||
updated_at: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when company was last updated',
|
||||
},
|
||||
custom_attributes: {
|
||||
type: 'object',
|
||||
description: 'Custom attributes set on the company',
|
||||
},
|
||||
tags: { type: 'object', description: 'Tags associated with the company' },
|
||||
segments: { type: 'object', description: 'Segments the company belongs to' },
|
||||
},
|
||||
},
|
||||
},
|
||||
pages: {
|
||||
type: 'object',
|
||||
description: 'Pagination information',
|
||||
properties: {
|
||||
type: { type: 'string', description: 'Pages type identifier' },
|
||||
page: { type: 'number', description: 'Current page number' },
|
||||
per_page: { type: 'number', description: 'Number of results per page' },
|
||||
total_pages: { type: 'number', description: 'Total number of pages' },
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (list_companies)' },
|
||||
total_count: { type: 'number', description: 'Total number of companies' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -96,16 +96,52 @@ export const intercomListContactsTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
type: 'object',
|
||||
description: 'List of contacts',
|
||||
properties: {
|
||||
contacts: { type: 'array', description: 'Array of contact objects' },
|
||||
pages: { type: 'object', description: 'Pagination information' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
contacts: {
|
||||
type: 'array',
|
||||
description: 'Array of contact objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the contact' },
|
||||
type: { type: 'string', description: 'Object type (contact)' },
|
||||
role: { type: 'string', description: 'Role of the contact (user or lead)' },
|
||||
email: { type: 'string', description: 'Email address of the contact' },
|
||||
phone: { type: 'string', description: 'Phone number of the contact' },
|
||||
name: { type: 'string', description: 'Name of the contact' },
|
||||
external_id: { type: 'string', description: 'External identifier for the contact' },
|
||||
created_at: { type: 'number', description: 'Unix timestamp when contact was created' },
|
||||
updated_at: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when contact was last updated',
|
||||
},
|
||||
workspace_id: { type: 'string', description: 'Workspace ID the contact belongs to' },
|
||||
custom_attributes: {
|
||||
type: 'object',
|
||||
description: 'Custom attributes set on the contact',
|
||||
},
|
||||
tags: { type: 'object', description: 'Tags associated with the contact' },
|
||||
companies: { type: 'object', description: 'Companies associated with the contact' },
|
||||
},
|
||||
},
|
||||
},
|
||||
pages: {
|
||||
type: 'object',
|
||||
description: 'Pagination information',
|
||||
properties: {
|
||||
type: { type: 'string', description: 'Pages type identifier' },
|
||||
page: { type: 'number', description: 'Current page number' },
|
||||
per_page: { type: 'number', description: 'Number of results per page' },
|
||||
total_pages: { type: 'number', description: 'Total number of pages' },
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (list_contacts)' },
|
||||
total_count: { type: 'number', description: 'Total number of contacts' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -112,16 +112,54 @@ export const intercomListConversationsTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
type: 'object',
|
||||
description: 'List of conversations',
|
||||
properties: {
|
||||
conversations: { type: 'array', description: 'Array of conversation objects' },
|
||||
pages: { type: 'object', description: 'Pagination information' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
conversations: {
|
||||
type: 'array',
|
||||
description: 'Array of conversation objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the conversation' },
|
||||
type: { type: 'string', description: 'Object type (conversation)' },
|
||||
title: { type: 'string', description: 'Title of the conversation' },
|
||||
created_at: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when conversation was created',
|
||||
},
|
||||
updated_at: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when conversation was last updated',
|
||||
},
|
||||
waiting_since: { type: 'number', description: 'Unix timestamp when waiting for reply' },
|
||||
open: { type: 'boolean', description: 'Whether the conversation is open' },
|
||||
state: { type: 'string', description: 'State of the conversation' },
|
||||
read: { type: 'boolean', description: 'Whether the conversation has been read' },
|
||||
priority: { type: 'string', description: 'Priority of the conversation' },
|
||||
admin_assignee_id: { type: 'number', description: 'ID of assigned admin' },
|
||||
team_assignee_id: { type: 'string', description: 'ID of assigned team' },
|
||||
tags: { type: 'object', description: 'Tags on the conversation' },
|
||||
source: { type: 'object', description: 'Source of the conversation' },
|
||||
contacts: { type: 'object', description: 'Contacts in the conversation' },
|
||||
},
|
||||
},
|
||||
},
|
||||
pages: {
|
||||
type: 'object',
|
||||
description: 'Pagination information',
|
||||
properties: {
|
||||
type: { type: 'string', description: 'Pages type identifier' },
|
||||
page: { type: 'number', description: 'Current page number' },
|
||||
per_page: { type: 'number', description: 'Number of results per page' },
|
||||
total_pages: { type: 'number', description: 'Total number of pages' },
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (list_conversations)' },
|
||||
total_count: { type: 'number', description: 'Total number of conversations' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -134,15 +134,39 @@ export const intercomReplyConversationTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
conversation: {
|
||||
type: 'object',
|
||||
description: 'Updated conversation with reply',
|
||||
description: 'Updated conversation object',
|
||||
properties: {
|
||||
conversation: { type: 'object', description: 'Updated conversation object' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
id: { type: 'string', description: 'Unique identifier for the conversation' },
|
||||
type: { type: 'string', description: 'Object type (conversation)' },
|
||||
title: { type: 'string', description: 'Title of the conversation' },
|
||||
created_at: { type: 'number', description: 'Unix timestamp when conversation was created' },
|
||||
updated_at: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when conversation was last updated',
|
||||
},
|
||||
waiting_since: { type: 'number', description: 'Unix timestamp when waiting for reply' },
|
||||
open: { type: 'boolean', description: 'Whether the conversation is open' },
|
||||
state: { type: 'string', description: 'State of the conversation' },
|
||||
read: { type: 'boolean', description: 'Whether the conversation has been read' },
|
||||
priority: { type: 'string', description: 'Priority of the conversation' },
|
||||
admin_assignee_id: { type: 'number', description: 'ID of assigned admin' },
|
||||
team_assignee_id: { type: 'string', description: 'ID of assigned team' },
|
||||
tags: { type: 'object', description: 'Tags on the conversation' },
|
||||
source: { type: 'object', description: 'Source of the conversation' },
|
||||
contacts: { type: 'object', description: 'Contacts in the conversation' },
|
||||
conversation_parts: { type: 'object', description: 'Parts of the conversation' },
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (reply_conversation)' },
|
||||
conversationId: { type: 'string', description: 'ID of the conversation' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -16,11 +16,67 @@ export interface IntercomSearchContactsParams {
|
||||
export interface IntercomSearchContactsResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
contacts: any[]
|
||||
pages?: any
|
||||
contacts: Array<{
|
||||
id: string
|
||||
type: string
|
||||
role: string
|
||||
email: string | null
|
||||
phone: string | null
|
||||
name: string | null
|
||||
avatar: string | null
|
||||
owner_id: string | null
|
||||
external_id: string | null
|
||||
created_at: number
|
||||
updated_at: number
|
||||
signed_up_at: number | null
|
||||
last_seen_at: number | null
|
||||
workspace_id: string
|
||||
custom_attributes: Record<string, any>
|
||||
tags: {
|
||||
type: string
|
||||
url: string
|
||||
data: any[]
|
||||
has_more: boolean
|
||||
total_count: number
|
||||
}
|
||||
notes: {
|
||||
type: string
|
||||
url: string
|
||||
data: any[]
|
||||
has_more: boolean
|
||||
total_count: number
|
||||
}
|
||||
companies: {
|
||||
type: string
|
||||
url: string
|
||||
data: any[]
|
||||
has_more: boolean
|
||||
total_count: number
|
||||
}
|
||||
location: {
|
||||
type: string
|
||||
city: string | null
|
||||
region: string | null
|
||||
country: string | null
|
||||
country_code: string | null
|
||||
continent_code: string | null
|
||||
}
|
||||
social_profiles: {
|
||||
type: string
|
||||
data: any[]
|
||||
}
|
||||
unsubscribed_from_emails: boolean
|
||||
[key: string]: any
|
||||
}>
|
||||
pages: {
|
||||
type: string
|
||||
page: number
|
||||
per_page: number
|
||||
total_pages: number
|
||||
}
|
||||
metadata: {
|
||||
operation: 'search_contacts'
|
||||
total_count?: number
|
||||
total_count: number
|
||||
}
|
||||
success: boolean
|
||||
}
|
||||
@@ -137,16 +193,63 @@ export const intercomSearchContactsTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
type: 'object',
|
||||
description: 'Search results',
|
||||
properties: {
|
||||
contacts: { type: 'array', description: 'Array of matching contact objects' },
|
||||
pages: { type: 'object', description: 'Pagination information' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
contacts: {
|
||||
type: 'array',
|
||||
description: 'Array of matching contact objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the contact' },
|
||||
type: { type: 'string', description: 'Object type (contact)' },
|
||||
role: { type: 'string', description: 'Role of the contact (user or lead)' },
|
||||
email: { type: 'string', description: 'Email address of the contact' },
|
||||
phone: { type: 'string', description: 'Phone number of the contact' },
|
||||
name: { type: 'string', description: 'Name of the contact' },
|
||||
avatar: { type: 'string', description: 'Avatar URL of the contact' },
|
||||
owner_id: { type: 'string', description: 'ID of the admin assigned to this contact' },
|
||||
external_id: { type: 'string', description: 'External identifier for the contact' },
|
||||
created_at: { type: 'number', description: 'Unix timestamp when contact was created' },
|
||||
updated_at: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when contact was last updated',
|
||||
},
|
||||
signed_up_at: { type: 'number', description: 'Unix timestamp when user signed up' },
|
||||
last_seen_at: { type: 'number', description: 'Unix timestamp when user was last seen' },
|
||||
workspace_id: { type: 'string', description: 'Workspace ID the contact belongs to' },
|
||||
custom_attributes: {
|
||||
type: 'object',
|
||||
description: 'Custom attributes set on the contact',
|
||||
},
|
||||
tags: { type: 'object', description: 'Tags associated with the contact' },
|
||||
notes: { type: 'object', description: 'Notes associated with the contact' },
|
||||
companies: { type: 'object', description: 'Companies associated with the contact' },
|
||||
location: { type: 'object', description: 'Location information for the contact' },
|
||||
social_profiles: { type: 'object', description: 'Social profiles of the contact' },
|
||||
unsubscribed_from_emails: {
|
||||
type: 'boolean',
|
||||
description: 'Whether contact is unsubscribed from emails',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
pages: {
|
||||
type: 'object',
|
||||
description: 'Pagination information',
|
||||
properties: {
|
||||
type: { type: 'string', description: 'Pages type identifier' },
|
||||
page: { type: 'number', description: 'Current page number' },
|
||||
per_page: { type: 'number', description: 'Number of results per page' },
|
||||
total_pages: { type: 'number', description: 'Total number of pages' },
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (search_contacts)' },
|
||||
total_count: { type: 'number', description: 'Total number of matching contacts' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -136,16 +136,57 @@ export const intercomSearchConversationsTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
type: 'object',
|
||||
description: 'Search results',
|
||||
properties: {
|
||||
conversations: { type: 'array', description: 'Array of matching conversation objects' },
|
||||
pages: { type: 'object', description: 'Pagination information' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
conversations: {
|
||||
type: 'array',
|
||||
description: 'Array of matching conversation objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Unique identifier for the conversation' },
|
||||
type: { type: 'string', description: 'Object type (conversation)' },
|
||||
title: { type: 'string', description: 'Title of the conversation' },
|
||||
created_at: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when conversation was created',
|
||||
},
|
||||
updated_at: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when conversation was last updated',
|
||||
},
|
||||
waiting_since: { type: 'number', description: 'Unix timestamp when waiting for reply' },
|
||||
open: { type: 'boolean', description: 'Whether the conversation is open' },
|
||||
state: { type: 'string', description: 'State of the conversation' },
|
||||
read: { type: 'boolean', description: 'Whether the conversation has been read' },
|
||||
priority: { type: 'string', description: 'Priority of the conversation' },
|
||||
admin_assignee_id: { type: 'number', description: 'ID of assigned admin' },
|
||||
team_assignee_id: { type: 'string', description: 'ID of assigned team' },
|
||||
tags: { type: 'object', description: 'Tags on the conversation' },
|
||||
source: { type: 'object', description: 'Source of the conversation' },
|
||||
contacts: { type: 'object', description: 'Contacts in the conversation' },
|
||||
},
|
||||
},
|
||||
},
|
||||
pages: {
|
||||
type: 'object',
|
||||
description: 'Pagination information',
|
||||
properties: {
|
||||
type: { type: 'string', description: 'Pages type identifier' },
|
||||
page: { type: 'number', description: 'Current page number' },
|
||||
per_page: { type: 'number', description: 'Number of results per page' },
|
||||
total_pages: { type: 'number', description: 'Total number of pages' },
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: {
|
||||
type: 'string',
|
||||
description: 'The operation performed (search_conversations)',
|
||||
},
|
||||
total_count: { type: 'number', description: 'Total number of matching conversations' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -188,15 +188,42 @@ export const intercomUpdateContactTool: ToolConfig<
|
||||
},
|
||||
|
||||
outputs: {
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
output: {
|
||||
contact: {
|
||||
type: 'object',
|
||||
description: 'Updated contact data',
|
||||
description: 'Updated contact object',
|
||||
properties: {
|
||||
contact: { type: 'object', description: 'Updated contact object' },
|
||||
metadata: { type: 'object', description: 'Operation metadata' },
|
||||
success: { type: 'boolean', description: 'Operation success' },
|
||||
id: { type: 'string', description: 'Unique identifier for the contact' },
|
||||
type: { type: 'string', description: 'Object type (contact)' },
|
||||
role: { type: 'string', description: 'Role of the contact (user or lead)' },
|
||||
email: { type: 'string', description: 'Email address of the contact' },
|
||||
phone: { type: 'string', description: 'Phone number of the contact' },
|
||||
name: { type: 'string', description: 'Name of the contact' },
|
||||
avatar: { type: 'string', description: 'Avatar URL of the contact' },
|
||||
owner_id: { type: 'string', description: 'ID of the admin assigned to this contact' },
|
||||
external_id: { type: 'string', description: 'External identifier for the contact' },
|
||||
created_at: { type: 'number', description: 'Unix timestamp when contact was created' },
|
||||
updated_at: { type: 'number', description: 'Unix timestamp when contact was last updated' },
|
||||
workspace_id: { type: 'string', description: 'Workspace ID the contact belongs to' },
|
||||
custom_attributes: { type: 'object', description: 'Custom attributes set on the contact' },
|
||||
tags: { type: 'object', description: 'Tags associated with the contact' },
|
||||
notes: { type: 'object', description: 'Notes associated with the contact' },
|
||||
companies: { type: 'object', description: 'Companies associated with the contact' },
|
||||
location: { type: 'object', description: 'Location information for the contact' },
|
||||
social_profiles: { type: 'object', description: 'Social profiles of the contact' },
|
||||
unsubscribed_from_emails: {
|
||||
type: 'boolean',
|
||||
description: 'Whether contact is unsubscribed from emails',
|
||||
},
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Operation metadata',
|
||||
properties: {
|
||||
operation: { type: 'string', description: 'The operation performed (update_contact)' },
|
||||
contactId: { type: 'string', description: 'ID of the updated contact' },
|
||||
},
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ export interface PineconeMatchResponse {
|
||||
export interface PineconeResponse extends ToolResponse {
|
||||
output: {
|
||||
matches?: PineconeMatchResponse[]
|
||||
upsertedCount?: number
|
||||
statusText?: string
|
||||
data?: Array<{
|
||||
values: number[]
|
||||
vector_type: 'dense' | 'sparse'
|
||||
|
||||
@@ -71,22 +71,11 @@ export const upsertTextTool: ToolConfig<PineconeUpsertTextParams, PineconeRespon
|
||||
},
|
||||
|
||||
transformResponse: async (response) => {
|
||||
// Handle empty response (201 Created)
|
||||
if (response.status === 201) {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
statusText: 'Created',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Handle response with content
|
||||
const data = await response.json()
|
||||
// Pinecone upsert returns 201 Created with empty body on success
|
||||
return {
|
||||
success: true,
|
||||
success: response.status === 201,
|
||||
output: {
|
||||
upsertedCount: data.upsertedCount || 0,
|
||||
statusText: response.status === 201 ? 'Created' : response.statusText,
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -96,9 +85,5 @@ export const upsertTextTool: ToolConfig<PineconeUpsertTextParams, PineconeRespon
|
||||
type: 'string',
|
||||
description: 'Status of the upsert operation',
|
||||
},
|
||||
upsertedCount: {
|
||||
type: 'number',
|
||||
description: 'Number of records successfully upserted',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -26,11 +26,17 @@ export const storageUploadTool: ToolConfig<
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The name of the storage bucket',
|
||||
},
|
||||
path: {
|
||||
fileName: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The path where the file will be stored (e.g., "folder/file.jpg")',
|
||||
description: 'The name of the file (e.g., "document.pdf", "image.jpg")',
|
||||
},
|
||||
path: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Optional folder path (e.g., "folder/subfolder/")',
|
||||
},
|
||||
fileContent: {
|
||||
type: 'string',
|
||||
@@ -60,7 +66,14 @@ export const storageUploadTool: ToolConfig<
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
return `https://${params.projectId}.supabase.co/storage/v1/object/${params.bucket}/${params.path}`
|
||||
// Combine folder path and fileName, ensuring proper formatting
|
||||
let fullPath = params.fileName
|
||||
if (params.path) {
|
||||
// Ensure path ends with / and doesn't have double slashes
|
||||
const folderPath = params.path.endsWith('/') ? params.path : `${params.path}/`
|
||||
fullPath = `${folderPath}${params.fileName}`
|
||||
}
|
||||
return `https://${params.projectId}.supabase.co/storage/v1/object/${params.bucket}/${fullPath}`
|
||||
},
|
||||
method: 'POST',
|
||||
headers: (params) => {
|
||||
|
||||
@@ -132,7 +132,8 @@ export interface SupabaseStorageUploadParams {
|
||||
apiKey: string
|
||||
projectId: string
|
||||
bucket: string
|
||||
path: string
|
||||
fileName: string
|
||||
path?: string
|
||||
fileContent: string
|
||||
contentType?: string
|
||||
upsert?: boolean
|
||||
|
||||
@@ -98,7 +98,12 @@ export const createFormTool: ToolConfig<TypeformCreateFormParams, TypeformCreate
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: data,
|
||||
output: {
|
||||
...data,
|
||||
welcome_screens: data.welcome_screens || [],
|
||||
thankyou_screens: data.thankyou_screens || [],
|
||||
fields: data.fields || [],
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -115,9 +120,29 @@ export const createFormTool: ToolConfig<TypeformCreateFormParams, TypeformCreate
|
||||
type: 'string',
|
||||
description: 'Form type',
|
||||
},
|
||||
settings: {
|
||||
type: 'object',
|
||||
description: 'Form settings object',
|
||||
},
|
||||
theme: {
|
||||
type: 'object',
|
||||
description: 'Theme reference',
|
||||
},
|
||||
workspace: {
|
||||
type: 'object',
|
||||
description: 'Workspace reference',
|
||||
},
|
||||
fields: {
|
||||
type: 'array',
|
||||
description: 'Array of created form fields',
|
||||
description: 'Array of created form fields (empty if none added)',
|
||||
},
|
||||
welcome_screens: {
|
||||
type: 'array',
|
||||
description: 'Array of welcome screens (empty if none configured)',
|
||||
},
|
||||
thankyou_screens: {
|
||||
type: 'array',
|
||||
description: 'Array of thank you screens',
|
||||
},
|
||||
_links: {
|
||||
type: 'object',
|
||||
|
||||
@@ -37,7 +37,12 @@ export const getFormTool: ToolConfig<TypeformGetFormParams, TypeformGetFormRespo
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: data,
|
||||
output: {
|
||||
...data,
|
||||
welcome_screens: data.welcome_screens || [],
|
||||
thankyou_screens: data.thankyou_screens || [],
|
||||
fields: data.fields || [],
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -72,12 +77,24 @@ export const getFormTool: ToolConfig<TypeformGetFormParams, TypeformGetFormRespo
|
||||
},
|
||||
welcome_screens: {
|
||||
type: 'array',
|
||||
description: 'Array of welcome screens',
|
||||
description: 'Array of welcome screens (empty if none configured)',
|
||||
},
|
||||
thankyou_screens: {
|
||||
type: 'array',
|
||||
description: 'Array of thank you screens',
|
||||
},
|
||||
created_at: {
|
||||
type: 'string',
|
||||
description: 'Form creation timestamp (ISO 8601 format)',
|
||||
},
|
||||
last_updated_at: {
|
||||
type: 'string',
|
||||
description: 'Form last update timestamp (ISO 8601 format)',
|
||||
},
|
||||
published_at: {
|
||||
type: 'string',
|
||||
description: 'Form publication timestamp (ISO 8601 format)',
|
||||
},
|
||||
_links: {
|
||||
type: 'object',
|
||||
description: 'Related resource links including public form URL',
|
||||
|
||||
@@ -221,20 +221,7 @@ export interface TypeformUpdateFormParams {
|
||||
|
||||
export interface TypeformUpdateFormResponse extends ToolResponse {
|
||||
output: {
|
||||
id: string
|
||||
title: string
|
||||
type: string
|
||||
created_at: string
|
||||
last_updated_at: string
|
||||
settings: Record<string, any>
|
||||
theme: Record<string, any>
|
||||
workspace?: {
|
||||
href: string
|
||||
}
|
||||
fields: Array<Record<string, any>>
|
||||
thankyou_screens?: Array<Record<string, any>>
|
||||
_links: Record<string, any>
|
||||
[key: string]: any
|
||||
message: string
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,54 +44,54 @@ export const updateFormTool: ToolConfig<TypeformUpdateFormParams, TypeformUpdate
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
// Check if response has content
|
||||
const text = await response.text()
|
||||
|
||||
// Handle empty responses
|
||||
if (!text || text.trim() === '') {
|
||||
if (response.ok) {
|
||||
// Success with no content (e.g., 204 No Content)
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
message: 'Form updated successfully',
|
||||
},
|
||||
}
|
||||
}
|
||||
throw new Error(`Request failed with status ${response.status}: ${response.statusText}`)
|
||||
}
|
||||
|
||||
// Try to parse as JSON
|
||||
let data: any
|
||||
try {
|
||||
data = JSON.parse(text)
|
||||
} catch {
|
||||
// If response is not OK and not JSON, throw with the raw text
|
||||
if (!response.ok) {
|
||||
throw new Error(`Request failed with status ${response.status}: ${text.slice(0, 200)}`)
|
||||
}
|
||||
throw new Error(`Invalid JSON response: ${text.slice(0, 200)}`)
|
||||
}
|
||||
|
||||
// Handle error responses from Typeform API
|
||||
if (!response.ok) {
|
||||
const errorMessage = data.description || data.message || data.error || JSON.stringify(data)
|
||||
throw new Error(`Typeform API error (${response.status}): ${errorMessage}`)
|
||||
}
|
||||
|
||||
// Return simple success message (Typeform PATCH returns minimal/no content on success)
|
||||
return {
|
||||
success: true,
|
||||
output: data,
|
||||
output: {
|
||||
message: 'Form updated successfully',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
id: {
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'Updated form unique identifier',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
description: 'Form title',
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
description: 'Form type',
|
||||
},
|
||||
settings: {
|
||||
type: 'object',
|
||||
description: 'Form settings',
|
||||
},
|
||||
theme: {
|
||||
type: 'object',
|
||||
description: 'Theme reference',
|
||||
},
|
||||
workspace: {
|
||||
type: 'object',
|
||||
description: 'Workspace reference',
|
||||
},
|
||||
fields: {
|
||||
type: 'array',
|
||||
description: 'Array of form fields',
|
||||
},
|
||||
welcome_screens: {
|
||||
type: 'array',
|
||||
description: 'Array of welcome screens',
|
||||
},
|
||||
thankyou_screens: {
|
||||
type: 'array',
|
||||
description: 'Array of thank you screens',
|
||||
},
|
||||
_links: {
|
||||
type: 'object',
|
||||
description: 'Related resource links',
|
||||
description: 'Success confirmation message',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user