chore: import upstream snapshot with attribution
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import type { GammaCheckStatusParams, GammaCheckStatusResponse } from '@/tools/gamma/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const checkStatusTool: ToolConfig<GammaCheckStatusParams, GammaCheckStatusResponse> = {
|
||||
id: 'gamma_check_status',
|
||||
name: 'Gamma Check Status',
|
||||
description:
|
||||
'Check the status of a Gamma generation job. Returns the gamma URL when completed, or error details if failed.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Gamma API key',
|
||||
},
|
||||
generationId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The generation ID returned by the Generate or Generate from Template tool',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://public-api.gamma.app/v1.0/generations/${params.generationId}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'X-API-KEY': params.apiKey,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response): Promise<GammaCheckStatusResponse> => {
|
||||
const data = await response.json()
|
||||
|
||||
const output: GammaCheckStatusResponse['output'] = {
|
||||
generationId: data.generationId ?? '',
|
||||
status: data.status ?? 'pending',
|
||||
gammaUrl: data.gammaUrl ?? null,
|
||||
}
|
||||
|
||||
if (data.credits) {
|
||||
output.credits = {
|
||||
deducted: data.credits.deducted ?? null,
|
||||
remaining: data.credits.remaining ?? null,
|
||||
}
|
||||
}
|
||||
|
||||
if (data.error) {
|
||||
output.error = {
|
||||
message: data.error.message ?? null,
|
||||
statusCode: data.error.statusCode ?? null,
|
||||
}
|
||||
}
|
||||
|
||||
return { success: true, output }
|
||||
},
|
||||
|
||||
outputs: {
|
||||
generationId: {
|
||||
type: 'string',
|
||||
description: 'The generation ID that was checked',
|
||||
},
|
||||
status: {
|
||||
type: 'string',
|
||||
description: 'Generation status: pending, completed, or failed',
|
||||
},
|
||||
gammaUrl: {
|
||||
type: 'string',
|
||||
description: 'URL of the generated gamma (only present when status is completed)',
|
||||
optional: true,
|
||||
},
|
||||
credits: {
|
||||
type: 'object',
|
||||
description: 'Credit usage information (only present when status is completed)',
|
||||
optional: true,
|
||||
properties: {
|
||||
deducted: {
|
||||
type: 'number',
|
||||
description: 'Number of credits deducted for this generation',
|
||||
optional: true,
|
||||
},
|
||||
remaining: {
|
||||
type: 'number',
|
||||
description: 'Remaining credits in the account',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
error: {
|
||||
type: 'object',
|
||||
description: 'Error details (only present when status is failed)',
|
||||
optional: true,
|
||||
properties: {
|
||||
message: {
|
||||
type: 'string',
|
||||
description: 'Human-readable error message',
|
||||
optional: true,
|
||||
},
|
||||
statusCode: {
|
||||
type: 'number',
|
||||
description: 'HTTP status code of the error',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
import type { GammaGenerateParams, GammaGenerateResponse } from '@/tools/gamma/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const generateTool: ToolConfig<GammaGenerateParams, GammaGenerateResponse> = {
|
||||
id: 'gamma_generate',
|
||||
name: 'Gamma Generate',
|
||||
description:
|
||||
'Generate a new Gamma presentation, document, webpage, or social post from text input.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Gamma API key',
|
||||
},
|
||||
inputText: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Text and image URLs used to generate your gamma (1-100,000 tokens)',
|
||||
},
|
||||
textMode: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'How to handle input text: generate (AI expands), condense (AI summarizes), or preserve (keep as-is)',
|
||||
},
|
||||
format: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Output format: presentation, document, webpage, or social (default: presentation)',
|
||||
},
|
||||
themeId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Custom Gamma workspace theme ID (use List Themes to find available themes)',
|
||||
},
|
||||
numCards: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of cards/slides to generate (1-60 for Pro, 1-75 for Ultra; default: 10)',
|
||||
},
|
||||
cardSplit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'How to split content into cards: auto or inputTextBreaks (default: auto)',
|
||||
},
|
||||
cardDimensions: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Card aspect ratio. Presentation: fluid, 16x9, 4x3. Document: fluid, pageless, letter, a4. Social: 1x1, 4x5, 9x16',
|
||||
},
|
||||
additionalInstructions: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Additional instructions for the AI generation (max 2000 chars)',
|
||||
},
|
||||
exportAs: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Automatically export the generated gamma as pdf or pptx',
|
||||
},
|
||||
folderIds: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated folder IDs to store the generated gamma in',
|
||||
},
|
||||
textAmount: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Amount of text per card: brief, medium, detailed, or extensive',
|
||||
},
|
||||
textTone: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Tone of the generated text, e.g. "professional", "casual" (max 500 chars)',
|
||||
},
|
||||
textAudience: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Target audience for the generated text, e.g. "executives", "students" (max 500 chars)',
|
||||
},
|
||||
textLanguage: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Language code for the generated text (default: en)',
|
||||
},
|
||||
imageSource: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Where to source images: aiGenerated, pictographic, unsplash, webAllImages, webFreeToUse, webFreeToUseCommercially, giphy, placeholder, or noImages',
|
||||
},
|
||||
imageModel: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'AI image generation model to use when imageSource is aiGenerated',
|
||||
},
|
||||
imageStyle: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Style directive for AI-generated images, e.g. "watercolor", "photorealistic" (max 500 chars)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://public-api.gamma.app/v1.0/generations',
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
'X-API-KEY': params.apiKey,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, unknown> = {
|
||||
inputText: params.inputText,
|
||||
textMode: params.textMode,
|
||||
}
|
||||
|
||||
if (params.format) body.format = params.format
|
||||
if (params.themeId) body.themeId = params.themeId
|
||||
if (params.numCards) body.numCards = params.numCards
|
||||
if (params.cardSplit) body.cardSplit = params.cardSplit
|
||||
if (params.additionalInstructions) body.additionalInstructions = params.additionalInstructions
|
||||
if (params.exportAs) body.exportAs = params.exportAs
|
||||
if (params.folderIds) {
|
||||
body.folderIds = params.folderIds.split(',').map((id: string) => id.trim())
|
||||
}
|
||||
|
||||
const textOptions: Record<string, unknown> = {}
|
||||
if (params.textAmount) textOptions.amount = params.textAmount
|
||||
if (params.textTone) textOptions.tone = params.textTone
|
||||
if (params.textAudience) textOptions.audience = params.textAudience
|
||||
if (params.textLanguage) textOptions.language = params.textLanguage
|
||||
if (Object.keys(textOptions).length > 0) body.textOptions = textOptions
|
||||
|
||||
const imageOptions: Record<string, unknown> = {}
|
||||
if (params.imageSource) imageOptions.source = params.imageSource
|
||||
if (params.imageModel) imageOptions.model = params.imageModel
|
||||
if (params.imageStyle) imageOptions.style = params.imageStyle
|
||||
if (Object.keys(imageOptions).length > 0) body.imageOptions = imageOptions
|
||||
|
||||
const cardOptions: Record<string, unknown> = {}
|
||||
if (params.cardDimensions) cardOptions.dimensions = params.cardDimensions
|
||||
if (Object.keys(cardOptions).length > 0) body.cardOptions = cardOptions
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
generationId: data.generationId ?? '',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
generationId: {
|
||||
type: 'string',
|
||||
description: 'The ID of the generation job. Use with Check Status to poll for completion.',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
import type {
|
||||
GammaGenerateFromTemplateParams,
|
||||
GammaGenerateFromTemplateResponse,
|
||||
} from '@/tools/gamma/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const generateFromTemplateTool: ToolConfig<
|
||||
GammaGenerateFromTemplateParams,
|
||||
GammaGenerateFromTemplateResponse
|
||||
> = {
|
||||
id: 'gamma_generate_from_template',
|
||||
name: 'Gamma Generate from Template',
|
||||
description: 'Generate a new Gamma by adapting an existing template with a prompt.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Gamma API key',
|
||||
},
|
||||
gammaId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the template gamma to adapt',
|
||||
},
|
||||
prompt: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Instructions for how to adapt the template (1-100,000 tokens)',
|
||||
},
|
||||
themeId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Custom Gamma workspace theme ID to apply',
|
||||
},
|
||||
exportAs: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Automatically export the generated gamma as pdf or pptx',
|
||||
},
|
||||
folderIds: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated folder IDs to store the generated gamma in',
|
||||
},
|
||||
imageModel: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'AI image generation model to use when imageSource is aiGenerated',
|
||||
},
|
||||
imageStyle: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Style directive for AI-generated images, e.g. "watercolor", "photorealistic" (max 500 chars)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://public-api.gamma.app/v1.0/generations/from-template',
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
'X-API-KEY': params.apiKey,
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, unknown> = {
|
||||
gammaId: params.gammaId,
|
||||
prompt: params.prompt,
|
||||
}
|
||||
|
||||
if (params.themeId) body.themeId = params.themeId
|
||||
if (params.exportAs) body.exportAs = params.exportAs
|
||||
if (params.folderIds) {
|
||||
body.folderIds = params.folderIds.split(',').map((id: string) => id.trim())
|
||||
}
|
||||
|
||||
const imageOptions: Record<string, unknown> = {}
|
||||
if (params.imageModel) imageOptions.model = params.imageModel
|
||||
if (params.imageStyle) imageOptions.style = params.imageStyle
|
||||
if (Object.keys(imageOptions).length > 0) body.imageOptions = imageOptions
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
generationId: data.generationId ?? '',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
generationId: {
|
||||
type: 'string',
|
||||
description: 'The ID of the generation job. Use with Check Status to poll for completion.',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { checkStatusTool } from '@/tools/gamma/check_status'
|
||||
import { generateTool } from '@/tools/gamma/generate'
|
||||
import { generateFromTemplateTool } from '@/tools/gamma/generate_from_template'
|
||||
import { listFoldersTool } from '@/tools/gamma/list_folders'
|
||||
import { listThemesTool } from '@/tools/gamma/list_themes'
|
||||
|
||||
export const gammaGenerateTool = generateTool
|
||||
export const gammaGenerateFromTemplateTool = generateFromTemplateTool
|
||||
export const gammaCheckStatusTool = checkStatusTool
|
||||
export const gammaListThemesTool = listThemesTool
|
||||
export const gammaListFoldersTool = listFoldersTool
|
||||
@@ -0,0 +1,91 @@
|
||||
import type { GammaListFoldersParams, GammaListFoldersResponse } from '@/tools/gamma/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const listFoldersTool: ToolConfig<GammaListFoldersParams, GammaListFoldersResponse> = {
|
||||
id: 'gamma_list_folders',
|
||||
name: 'Gamma List Folders',
|
||||
description:
|
||||
'List available folders in your Gamma workspace. Returns folder IDs and names for organizing generated content.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Gamma API key',
|
||||
},
|
||||
query: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Search query to filter folders by name (case-sensitive)',
|
||||
},
|
||||
limit: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of folders to return per page (max 50)',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination cursor from a previous response (nextCursor) to fetch the next page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://public-api.gamma.app/v1.0/folders')
|
||||
if (params.query) url.searchParams.append('query', params.query)
|
||||
if (params.limit) url.searchParams.append('limit', String(params.limit))
|
||||
if (params.after) url.searchParams.append('after', params.after)
|
||||
return url.toString()
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'X-API-KEY': params.apiKey,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
const items = Array.isArray(data.data) ? data.data : Array.isArray(data) ? data : []
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
folders: items.map((folder: { id?: string; name?: string }) => ({
|
||||
id: folder.id ?? '',
|
||||
name: folder.name ?? '',
|
||||
})),
|
||||
hasMore: data.hasMore ?? false,
|
||||
nextCursor: data.nextCursor ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
folders: {
|
||||
type: 'array',
|
||||
description: 'List of available folders',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Folder ID (use with folderIds parameter)' },
|
||||
name: { type: 'string', description: 'Folder display name' },
|
||||
},
|
||||
},
|
||||
},
|
||||
hasMore: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more results are available on the next page',
|
||||
},
|
||||
nextCursor: {
|
||||
type: 'string',
|
||||
description: 'Pagination cursor to pass as the after parameter for the next page',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
import type { GammaListThemesParams, GammaListThemesResponse } from '@/tools/gamma/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const listThemesTool: ToolConfig<GammaListThemesParams, GammaListThemesResponse> = {
|
||||
id: 'gamma_list_themes',
|
||||
name: 'Gamma List Themes',
|
||||
description:
|
||||
'List available themes in your Gamma workspace. Returns theme IDs, names, and keywords for styling.',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Gamma API key',
|
||||
},
|
||||
query: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Search query to filter themes by name (case-insensitive)',
|
||||
},
|
||||
limit: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum number of themes to return per page (max 50)',
|
||||
},
|
||||
after: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination cursor from a previous response (nextCursor) to fetch the next page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const url = new URL('https://public-api.gamma.app/v1.0/themes')
|
||||
if (params.query) url.searchParams.append('query', params.query)
|
||||
if (params.limit) url.searchParams.append('limit', String(params.limit))
|
||||
if (params.after) url.searchParams.append('after', params.after)
|
||||
return url.toString()
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'X-API-KEY': params.apiKey,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
const items = Array.isArray(data.data) ? data.data : Array.isArray(data) ? data : []
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
themes: items.map(
|
||||
(theme: {
|
||||
id?: string
|
||||
name?: string
|
||||
type?: string
|
||||
colorKeywords?: string[]
|
||||
toneKeywords?: string[]
|
||||
}) => ({
|
||||
id: theme.id ?? '',
|
||||
name: theme.name ?? '',
|
||||
type: theme.type ?? '',
|
||||
colorKeywords: theme.colorKeywords ?? [],
|
||||
toneKeywords: theme.toneKeywords ?? [],
|
||||
})
|
||||
),
|
||||
hasMore: data.hasMore ?? false,
|
||||
nextCursor: data.nextCursor ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
themes: {
|
||||
type: 'array',
|
||||
description: 'List of available themes',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Theme ID (use with themeId parameter)' },
|
||||
name: { type: 'string', description: 'Theme display name' },
|
||||
type: { type: 'string', description: 'Theme type: standard or custom' },
|
||||
colorKeywords: {
|
||||
type: 'array',
|
||||
description: 'Color descriptors for this theme',
|
||||
items: { type: 'string', description: 'Color keyword' },
|
||||
},
|
||||
toneKeywords: {
|
||||
type: 'array',
|
||||
description: 'Tone descriptors for this theme',
|
||||
items: { type: 'string', description: 'Tone keyword' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
hasMore: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more results are available on the next page',
|
||||
},
|
||||
nextCursor: {
|
||||
type: 'string',
|
||||
description: 'Pagination cursor to pass as the after parameter for the next page',
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
import type { ToolResponse } from '@/tools/types'
|
||||
|
||||
/**
|
||||
* Base parameters shared across all Gamma API tools.
|
||||
*/
|
||||
interface GammaBaseParams {
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for the Generate a Gamma tool.
|
||||
*/
|
||||
export interface GammaGenerateParams extends GammaBaseParams {
|
||||
inputText: string
|
||||
textMode: 'generate' | 'condense' | 'preserve'
|
||||
format?: 'presentation' | 'document' | 'webpage' | 'social'
|
||||
themeId?: string
|
||||
numCards?: number
|
||||
cardSplit?: 'auto' | 'inputTextBreaks'
|
||||
cardDimensions?: string
|
||||
additionalInstructions?: string
|
||||
exportAs?: 'pdf' | 'pptx'
|
||||
folderIds?: string
|
||||
textAmount?: 'brief' | 'medium' | 'detailed' | 'extensive'
|
||||
textTone?: string
|
||||
textAudience?: string
|
||||
textLanguage?: string
|
||||
imageSource?:
|
||||
| 'aiGenerated'
|
||||
| 'pictographic'
|
||||
| 'unsplash'
|
||||
| 'webAllImages'
|
||||
| 'webFreeToUse'
|
||||
| 'webFreeToUseCommercially'
|
||||
| 'giphy'
|
||||
| 'placeholder'
|
||||
| 'noImages'
|
||||
imageModel?: string
|
||||
imageStyle?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for the Generate from Template tool.
|
||||
*/
|
||||
export interface GammaGenerateFromTemplateParams extends GammaBaseParams {
|
||||
gammaId: string
|
||||
prompt: string
|
||||
themeId?: string
|
||||
exportAs?: 'pdf' | 'pptx'
|
||||
folderIds?: string
|
||||
imageModel?: string
|
||||
imageStyle?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for the Check Generation Status tool.
|
||||
*/
|
||||
export interface GammaCheckStatusParams extends GammaBaseParams {
|
||||
generationId: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for the List Themes tool.
|
||||
*/
|
||||
export interface GammaListThemesParams extends GammaBaseParams {
|
||||
query?: string
|
||||
limit?: number
|
||||
after?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for the List Folders tool.
|
||||
*/
|
||||
export interface GammaListFoldersParams extends GammaBaseParams {
|
||||
query?: string
|
||||
limit?: number
|
||||
after?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Response for the Generate tool.
|
||||
*/
|
||||
export interface GammaGenerateResponse extends ToolResponse {
|
||||
output: {
|
||||
generationId: string
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Response for the Generate from Template tool.
|
||||
*/
|
||||
export interface GammaGenerateFromTemplateResponse extends ToolResponse {
|
||||
output: {
|
||||
generationId: string
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Response for the Check Status tool.
|
||||
*/
|
||||
export interface GammaCheckStatusResponse extends ToolResponse {
|
||||
output: {
|
||||
generationId: string
|
||||
status: 'pending' | 'completed' | 'failed'
|
||||
gammaUrl: string | null
|
||||
credits?: {
|
||||
deducted: number | null
|
||||
remaining: number | null
|
||||
}
|
||||
error?: {
|
||||
message: string | null
|
||||
statusCode: number | null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme object from the Gamma API.
|
||||
*/
|
||||
interface GammaTheme {
|
||||
id: string
|
||||
name: string
|
||||
type: string
|
||||
colorKeywords: string[]
|
||||
toneKeywords: string[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Response for the List Themes tool.
|
||||
*/
|
||||
export interface GammaListThemesResponse extends ToolResponse {
|
||||
output: {
|
||||
themes: GammaTheme[]
|
||||
hasMore: boolean
|
||||
nextCursor: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Folder object from the Gamma API.
|
||||
*/
|
||||
interface GammaFolder {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Response for the List Folders tool.
|
||||
*/
|
||||
export interface GammaListFoldersResponse extends ToolResponse {
|
||||
output: {
|
||||
folders: GammaFolder[]
|
||||
hasMore: boolean
|
||||
nextCursor: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export type GammaResponse =
|
||||
| GammaGenerateResponse
|
||||
| GammaGenerateFromTemplateResponse
|
||||
| GammaCheckStatusResponse
|
||||
| GammaListThemesResponse
|
||||
| GammaListFoldersResponse
|
||||
Reference in New Issue
Block a user