kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: improve web examples
rodzic
7759aa43d3
commit
7b5f7e8f97
|
@ -79,7 +79,10 @@ export function registerV1CreateDeployment(
|
|||
|
||||
if (!project) {
|
||||
// Used for testing e2e fixtures in the development marketplace
|
||||
const isPrivate = !(user.username === 'dev' && env.isDev)
|
||||
const isPrivate = !(
|
||||
(user.username === 'dev' && env.isDev) ||
|
||||
user.username === 'agentic'
|
||||
)
|
||||
|
||||
// Upsert the project if it doesn't already exist
|
||||
// The typecast is necessary here because we're not populating the
|
||||
|
|
|
@ -63,7 +63,10 @@ export function registerV1CreateProject(
|
|||
)
|
||||
|
||||
// Used for testing e2e fixtures in the development marketplace
|
||||
const isPrivate = !(user.username === 'dev' && env.isDev)
|
||||
const isPrivate = !(
|
||||
(user.username === 'dev' && env.isDev) ||
|
||||
user.username === 'agentic'
|
||||
)
|
||||
|
||||
const [project] = await db
|
||||
.insert(schema.projects)
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import { sha256 } from '@agentic/platform-core'
|
||||
|
||||
export async function createConsumerToken(): Promise<string> {
|
||||
const hash = await sha256()
|
||||
|
||||
return hash.slice(0, 24)
|
||||
return sha256()
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import Link from 'next/link'
|
||||
|
||||
import { DemandSideCTA } from '@/components/demand-side-cta'
|
||||
import { ExampleUsage } from '@/components/example-usage'
|
||||
import { GitHubStarCounter } from '@/components/github-star-counter'
|
||||
import { githubUrl, twitterUrl } from '@/lib/config'
|
||||
|
||||
import { ExampleUsage } from './example-usage'
|
||||
|
||||
export default function TheBestDamnLandingPageEver() {
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
import { toJsxRuntime } from 'hast-util-to-jsx-runtime'
|
||||
import { Fragment, type JSX, useEffect, useState } from 'react'
|
||||
import { CheckIcon, CopyIcon } from 'lucide-react'
|
||||
import {
|
||||
Fragment,
|
||||
type JSX,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState
|
||||
} from 'react'
|
||||
import { jsx, jsxs } from 'react/jsx-runtime'
|
||||
import { type BundledLanguage, codeToHast } from 'shiki/bundle/web'
|
||||
|
||||
import { toastError } from '@/lib/notifications'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
import { LoadingIndicator } from './loading-indicator'
|
||||
import { Button } from './ui/button'
|
||||
|
||||
export async function highlight({
|
||||
code,
|
||||
|
@ -51,10 +63,62 @@ export function CodeBlock({
|
|||
className?: string
|
||||
}) {
|
||||
const [nodes, setNodes] = useState(initial)
|
||||
const [isCopied, setIsCopied] = useState(false)
|
||||
const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
void highlight({ code, lang, theme, className }).then(setNodes)
|
||||
}, [code, lang, theme, className])
|
||||
void highlight({
|
||||
code,
|
||||
lang,
|
||||
theme,
|
||||
className: 'rounded-sm w-full text-wrap p-4 text-sm'
|
||||
}).then(setNodes)
|
||||
}, [code, lang, theme])
|
||||
|
||||
return nodes ?? <LoadingIndicator />
|
||||
const onCopy = useCallback(() => {
|
||||
;(async () => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(code)
|
||||
setIsCopied(true)
|
||||
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current)
|
||||
timeoutRef.current = null
|
||||
}
|
||||
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
timeoutRef.current = null
|
||||
setIsCopied(false)
|
||||
}, 2000)
|
||||
} catch {
|
||||
setIsCopied(true)
|
||||
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current)
|
||||
timeoutRef.current = null
|
||||
}
|
||||
void toastError('Error copying code to clipboard')
|
||||
}
|
||||
})()
|
||||
}, [code, timeoutRef])
|
||||
|
||||
return (
|
||||
<div className={cn('relative group rounded-sm w-full', className)}>
|
||||
{nodes ? (
|
||||
<>
|
||||
{nodes}
|
||||
|
||||
<Button
|
||||
variant='outline'
|
||||
className='absolute top-4 right-4 px-2.5! opacity-0 group-hover:opacity-100 group-hover:duration-0 transition-opacity duration-150'
|
||||
onClick={onCopy}
|
||||
>
|
||||
{isCopied ? <CheckIcon /> : <CopyIcon />}
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<LoadingIndicator />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
|
||||
import { useLocalStorage } from 'react-use'
|
||||
|
||||
import { useAgentic } from '@/components/agentic-provider'
|
||||
import { CodeBlock } from '@/components/code-block'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
import {
|
||||
defaultConfig,
|
||||
type DeveloperConfig,
|
||||
getCodeForDeveloperConfig,
|
||||
type HTTPTarget,
|
||||
httpTargetLabels,
|
||||
httpTargets,
|
||||
|
@ -23,16 +25,85 @@ import {
|
|||
tsFrameworkTargetLabels,
|
||||
tsFrameworkTargets
|
||||
} from '@/lib/developer-config'
|
||||
import { useQuery } from '@/lib/query-client'
|
||||
|
||||
import { LoadingIndicator } from './loading-indicator'
|
||||
|
||||
export function ExampleUsage() {
|
||||
const ctx = useAgentic()
|
||||
|
||||
const [config, setConfig] = useLocalStorage<DeveloperConfig>(
|
||||
'config',
|
||||
defaultConfig
|
||||
)
|
||||
|
||||
// TODO: make this configurable
|
||||
// TODO: allow to take the project and/or consumer in as props
|
||||
// TODO: need a way of fetching a project and target deployment; same as in `AgenticToolClient.fromIdentifier` (currently only supports latest)
|
||||
const projectIdentifier = '@agentic/search'
|
||||
|
||||
// Load the public project
|
||||
const {
|
||||
data: project,
|
||||
isLoading,
|
||||
isError
|
||||
} = useQuery({
|
||||
queryKey: ['project', projectIdentifier],
|
||||
queryFn: () =>
|
||||
ctx!.api.getPublicProjectByIdentifier({
|
||||
projectIdentifier,
|
||||
populate: ['lastPublishedDeployment']
|
||||
}),
|
||||
enabled: !!ctx
|
||||
})
|
||||
|
||||
// If the user is authenticated, check if they have an active subscription to
|
||||
// this project
|
||||
// TODO: use consumer for apiKey
|
||||
// const {
|
||||
// data: consumer,
|
||||
// isLoading: isConsumerLoading
|
||||
// // isError: isConsumerError
|
||||
// } = useQuery({
|
||||
// queryKey: [
|
||||
// 'project',
|
||||
// projectIdentifier,
|
||||
// 'user',
|
||||
// ctx?.api.authSession?.user.id
|
||||
// ],
|
||||
// queryFn: () =>
|
||||
// ctx!.api.getConsumerByProjectIdentifier({
|
||||
// projectIdentifier
|
||||
// }),
|
||||
// enabled: !!ctx?.isAuthenticated
|
||||
// })
|
||||
|
||||
if (isLoading || !config) {
|
||||
return <LoadingIndicator className='w-full max-w-3xl' />
|
||||
}
|
||||
|
||||
// TODO: allow to target a specific deployment
|
||||
const deployment = project?.lastPublishedDeployment
|
||||
|
||||
if (isError || !project || !deployment) {
|
||||
return (
|
||||
<div>
|
||||
Error loading project. Please refresh the page or contact{' '}
|
||||
<a href='mailto:support@agentic.so'>support@agentic.so</a>.
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const codeSnippet = getCodeForDeveloperConfig({
|
||||
config,
|
||||
project,
|
||||
deployment,
|
||||
identifier: projectIdentifier
|
||||
})
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
defaultValue={config!.target}
|
||||
defaultValue={config.target}
|
||||
onValueChange={(value) =>
|
||||
setConfig({
|
||||
...defaultConfig,
|
||||
|
@ -40,7 +111,7 @@ export function ExampleUsage() {
|
|||
target: value as Target
|
||||
})
|
||||
}
|
||||
className='w-full max-w-2xl'
|
||||
className='w-full max-w-3xl'
|
||||
>
|
||||
<TabsList>
|
||||
{targets.map((target) => (
|
||||
|
@ -52,7 +123,7 @@ export function ExampleUsage() {
|
|||
|
||||
<TabsContent value='mcp' className='w-full'>
|
||||
<Tabs
|
||||
defaultValue={config!.mcpClientTarget}
|
||||
defaultValue={config.mcpClientTarget}
|
||||
onValueChange={(value) =>
|
||||
setConfig({
|
||||
...defaultConfig,
|
||||
|
@ -80,11 +151,7 @@ export function ExampleUsage() {
|
|||
value={mcpClientTarget}
|
||||
className='w-full'
|
||||
>
|
||||
<CodeBlock
|
||||
code={JSON.stringify(config, null, 2)}
|
||||
lang='json'
|
||||
className='p-4 rounded-sm w-full'
|
||||
/>
|
||||
<CodeBlock code={codeSnippet.code} lang={codeSnippet.lang} />
|
||||
</TabsContent>
|
||||
))}
|
||||
</Tabs>
|
||||
|
@ -92,7 +159,7 @@ export function ExampleUsage() {
|
|||
|
||||
<TabsContent value='typescript' className='w-full'>
|
||||
<Tabs
|
||||
defaultValue={config!.tsFrameworkTarget ?? 'ai'}
|
||||
defaultValue={config.tsFrameworkTarget ?? 'ai'}
|
||||
onValueChange={(value) =>
|
||||
setConfig({
|
||||
...defaultConfig,
|
||||
|
@ -102,12 +169,12 @@ export function ExampleUsage() {
|
|||
}
|
||||
className='w-full'
|
||||
>
|
||||
<TabsList className='h-auto flex-wrap'>
|
||||
<TabsList className='w-full h-auto flex-wrap'>
|
||||
{tsFrameworkTargets.map((framework) => (
|
||||
<TabsTrigger
|
||||
key={framework}
|
||||
value={framework}
|
||||
className='cursor-pointer'
|
||||
className='cursor-pointer text-xs!'
|
||||
>
|
||||
{tsFrameworkTargetLabels[framework]}
|
||||
</TabsTrigger>
|
||||
|
@ -116,11 +183,7 @@ export function ExampleUsage() {
|
|||
|
||||
{tsFrameworkTargets.map((framework) => (
|
||||
<TabsContent key={framework} value={framework} className='w-full'>
|
||||
<CodeBlock
|
||||
code={JSON.stringify(config, null, 2)}
|
||||
lang='ts'
|
||||
className='p-4 rounded-sm w-full'
|
||||
/>
|
||||
<CodeBlock code={codeSnippet.code} lang={codeSnippet.lang} />
|
||||
</TabsContent>
|
||||
))}
|
||||
</Tabs>
|
||||
|
@ -128,7 +191,7 @@ export function ExampleUsage() {
|
|||
|
||||
<TabsContent value='python' className='w-full'>
|
||||
<Tabs
|
||||
defaultValue={config!.pyFrameworkTarget}
|
||||
defaultValue={config.pyFrameworkTarget}
|
||||
onValueChange={(value) =>
|
||||
setConfig({
|
||||
...defaultConfig,
|
||||
|
@ -152,11 +215,7 @@ export function ExampleUsage() {
|
|||
|
||||
{pyFrameworkTargets.map((framework) => (
|
||||
<TabsContent key={framework} value={framework} className='w-full'>
|
||||
<CodeBlock
|
||||
code={JSON.stringify(config, null, 2)}
|
||||
lang='py'
|
||||
className='p-4 rounded-sm w-full'
|
||||
/>
|
||||
<CodeBlock code={codeSnippet.code} lang={codeSnippet.lang} />
|
||||
</TabsContent>
|
||||
))}
|
||||
</Tabs>
|
||||
|
@ -164,7 +223,7 @@ export function ExampleUsage() {
|
|||
|
||||
<TabsContent value='http' className='w-full'>
|
||||
<Tabs
|
||||
defaultValue={config!.httpTarget}
|
||||
defaultValue={config.httpTarget}
|
||||
onValueChange={(value) =>
|
||||
setConfig({
|
||||
...defaultConfig,
|
||||
|
@ -188,11 +247,7 @@ export function ExampleUsage() {
|
|||
|
||||
{httpTargets.map((httpTarget) => (
|
||||
<TabsContent key={httpTarget} value={httpTarget} className='w-full'>
|
||||
<CodeBlock
|
||||
code={JSON.stringify(config, null, 2)}
|
||||
lang='bash'
|
||||
className='p-4 rounded-sm w-full'
|
||||
/>
|
||||
<CodeBlock code={codeSnippet.code} lang={codeSnippet.lang} />
|
||||
</TabsContent>
|
||||
))}
|
||||
</Tabs>
|
|
@ -5,6 +5,7 @@
|
|||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.fill {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import type { Deployment, Project } from '@agentic/platform-types'
|
||||
import type { BundledLanguage } from 'shiki/bundle/web'
|
||||
import { assert } from '@agentic/platform-core'
|
||||
|
||||
import { gatewayBaseUrl } from './config'
|
||||
|
@ -24,7 +25,7 @@ export const httpTargets: (keyof typeof httpTargetLabels)[] = Object.keys(
|
|||
export type HTTPTarget = (typeof httpTargets)[number]
|
||||
|
||||
export const mcpClientTargetLabels = {
|
||||
any: 'Any MCP Client',
|
||||
url: 'MCP Server URL',
|
||||
'claude-desktop': 'Claude Desktop',
|
||||
raycast: 'Raycast',
|
||||
cursor: 'Cursor',
|
||||
|
@ -41,8 +42,8 @@ export const tsFrameworkTargetLabels = {
|
|||
'openai-chat': 'OpenAI Chat',
|
||||
'openai-responses': 'OpenAI Responses',
|
||||
langchain: 'LangChain',
|
||||
mastra: 'Mastra',
|
||||
llamaindex: 'LlamaIndex',
|
||||
mastra: 'Mastra',
|
||||
'firebase-genkit': 'Firebase GenKit',
|
||||
xsai: 'xsAI'
|
||||
} as const
|
||||
|
@ -69,19 +70,25 @@ export type DeveloperConfig = {
|
|||
|
||||
export const defaultConfig: DeveloperConfig = {
|
||||
target: 'typescript',
|
||||
mcpClientTarget: 'any',
|
||||
mcpClientTarget: 'url',
|
||||
tsFrameworkTarget: 'ai',
|
||||
pyFrameworkTarget: 'openai',
|
||||
httpTarget: 'curl'
|
||||
}
|
||||
|
||||
export type CodeSnippet = {
|
||||
code: string
|
||||
lang: BundledLanguage
|
||||
// install?: string // TODO
|
||||
}
|
||||
|
||||
export function getCodeForDeveloperConfig(opts: {
|
||||
config: DeveloperConfig
|
||||
project: Project
|
||||
deployment: Deployment
|
||||
identifier: string
|
||||
tool?: string
|
||||
}): string {
|
||||
}): CodeSnippet {
|
||||
const { config } = opts
|
||||
|
||||
switch (config.target) {
|
||||
|
@ -90,8 +97,7 @@ export function getCodeForDeveloperConfig(opts: {
|
|||
case 'typescript':
|
||||
return getCodeForTSFrameworkConfig(opts)
|
||||
case 'python':
|
||||
return 'Python support is coming soon...'
|
||||
// return getCodeForPythonFrameworkConfig(opts)
|
||||
return getCodeForPythonFrameworkConfig(opts)
|
||||
case 'http':
|
||||
return getCodeForHTTPConfig(opts)
|
||||
}
|
||||
|
@ -101,21 +107,27 @@ export function getCodeForMCPClientConfig({
|
|||
identifier
|
||||
}: {
|
||||
identifier: string
|
||||
}): string {
|
||||
return `${gatewayBaseUrl}/${identifier}/mcp`
|
||||
}): CodeSnippet {
|
||||
return {
|
||||
code: `${gatewayBaseUrl}/${identifier}/mcp`,
|
||||
lang: 'bash'
|
||||
}
|
||||
}
|
||||
|
||||
export function getCodeForTSFrameworkConfig({
|
||||
config,
|
||||
identifier
|
||||
identifier,
|
||||
prompt = 'What is the latest news about AI?'
|
||||
}: {
|
||||
config: DeveloperConfig
|
||||
identifier: string
|
||||
}): string {
|
||||
prompt?: string
|
||||
}): CodeSnippet {
|
||||
switch (config.tsFrameworkTarget) {
|
||||
case 'ai':
|
||||
return `
|
||||
import { createAISDKTools } from '@agentic/ai'
|
||||
return {
|
||||
code: `
|
||||
import { createAISDKTools } from '@agentic/ai-sdk'
|
||||
import { AgenticToolClient } from '@agentic/platform-tool-client'
|
||||
import { openai } from '@ai-sdk/openai'
|
||||
import { generateText } from 'ai'
|
||||
|
@ -126,66 +138,221 @@ const result = await generateText({
|
|||
model: openai('gpt-4o-mini'),
|
||||
tools: createAISDKTools(searchTool),
|
||||
toolChoice: 'required',
|
||||
temperature: 0,
|
||||
system: 'You are a helpful assistant. Be as concise as possible.',
|
||||
prompt: 'What is the latest news about AI?'
|
||||
prompt: '${prompt}'
|
||||
})
|
||||
|
||||
console.log(result.toolResults[0])
|
||||
`.trim()
|
||||
`.trim(),
|
||||
lang: 'ts'
|
||||
}
|
||||
|
||||
case 'openai-chat':
|
||||
return `
|
||||
return {
|
||||
code: `
|
||||
import { AgenticToolClient } from '@agentic/platform-tool-client'
|
||||
import OpenAI from 'openai'
|
||||
|
||||
const openai = new OpenAI()
|
||||
const searchTool = await AgenticToolClient.fromIdentifier('${identifier}')
|
||||
|
||||
// This example uses OpenAI's Chat Completions API
|
||||
const res = await openai.chat.completions.create({
|
||||
model: 'gpt-4o-mini',
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: 'You are a helpful assistant. Be as concise as possible.'
|
||||
}
|
||||
{
|
||||
role: 'user',
|
||||
content: 'What is the latest news about AI?'
|
||||
content: '${prompt}'
|
||||
}
|
||||
],
|
||||
model: 'gpt-4o-mini',
|
||||
temperature: 0,
|
||||
tools: searchTool.functions.toolSpecs,
|
||||
tool_choice: 'required'
|
||||
})
|
||||
|
||||
const message = res.choices[0]!.message!
|
||||
const toolCall = message.tool_calls![0]!
|
||||
|
||||
const tool = searchTool.functions.get(toolCall.function.name)!
|
||||
const toolResult = await tool(toolCall.function.arguments)
|
||||
const toolCall = message.tool_calls![0]!.function!
|
||||
const toolResult = await searchTool.callTool(toolCall.name, toolCall.arguments)
|
||||
|
||||
console.log(toolResult)
|
||||
`.trim()
|
||||
}
|
||||
`.trim(),
|
||||
lang: 'ts'
|
||||
}
|
||||
|
||||
return ''
|
||||
case 'openai-responses':
|
||||
return {
|
||||
code: `
|
||||
import { AgenticToolClient } from '@agentic/platform-tool-client'
|
||||
import OpenAI from 'openai'
|
||||
|
||||
const openai = new OpenAI()
|
||||
const searchTool = await AgenticToolClient.fromIdentifier('${identifier}')
|
||||
|
||||
// This example uses OpenAI's newer Responses API
|
||||
const res = await openai.responses.create({
|
||||
model: 'gpt-4o-mini',
|
||||
tools: searchTool.functions.responsesToolSpecs,
|
||||
tool_choice: 'required',
|
||||
input: [
|
||||
{
|
||||
role: 'user',
|
||||
content: '${prompt}'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
const toolCall = res.output[0]
|
||||
const toolResult = await searchTool.callTool(toolCall.name, toolCall.arguments)
|
||||
|
||||
console.log(toolResult)
|
||||
`.trim(),
|
||||
lang: 'ts'
|
||||
}
|
||||
|
||||
case 'langchain':
|
||||
return {
|
||||
code: `
|
||||
import { createLangChainTools } from '@agentic/langchain'
|
||||
import { AgenticToolClient } from '@agentic/platform-tool-client'
|
||||
import { ChatPromptTemplate } from '@langchain/core/prompts'
|
||||
import { ChatOpenAI } from '@langchain/openai'
|
||||
import { AgentExecutor, createToolCallingAgent } from 'langchain/agents'
|
||||
|
||||
const searchTool = await AgenticToolClient.fromIdentifier('${identifier}')
|
||||
|
||||
const agent = createToolCallingAgent({
|
||||
llm: new ChatOpenAI({ model: 'gpt-4o-mini' }),
|
||||
tools: createLangChainTools(searchTool),
|
||||
prompt: ChatPromptTemplate.fromMessages([
|
||||
['placeholder', '{chat_history}'],
|
||||
['human', '{input}'],
|
||||
['placeholder', '{agent_scratchpad}']
|
||||
])
|
||||
})
|
||||
|
||||
const agentExecutor = new AgentExecutor({ agent, tools })
|
||||
|
||||
const result = await agentExecutor.invoke({
|
||||
input: '${prompt}'
|
||||
})
|
||||
|
||||
console.log(result.output)
|
||||
`.trim(),
|
||||
lang: 'ts'
|
||||
}
|
||||
|
||||
case 'llamaindex':
|
||||
return {
|
||||
code: `
|
||||
import { createLlamaIndexTools } from '@agentic/llamaindex'
|
||||
import { AgenticToolClient } from '@agentic/platform-tool-client'
|
||||
import { openai } from '@llamaindex/openai'
|
||||
import { agent } from '@llamaindex/workflow'
|
||||
|
||||
const searchTool = await AgenticToolClient.fromIdentifier('${identifier}')
|
||||
|
||||
const exampleAgent = agent({
|
||||
llm: openai({ model: 'gpt-4o-mini', temperature: 0 }),
|
||||
tools: createLlamaIndexTools(searchTool)
|
||||
})
|
||||
|
||||
const response = await exampleAgent.run(
|
||||
'${prompt}'
|
||||
)
|
||||
|
||||
console.log(response.data.result)
|
||||
`.trim(),
|
||||
lang: 'ts'
|
||||
}
|
||||
|
||||
case 'mastra':
|
||||
return {
|
||||
code: `
|
||||
import { createMastraTools } from '@agentic/mastra'
|
||||
import { AgenticToolClient } from '@agentic/platform-tool-client'
|
||||
import { openai } from '@ai-sdk/openai'
|
||||
import { Agent } from '@mastra/core/agent'
|
||||
|
||||
const searchTool = await AgenticToolClient.fromIdentifier('${identifier}')
|
||||
|
||||
const exampleAgent = new Agent({
|
||||
name: 'Example Agent',
|
||||
model: openai('gpt-4o-mini') as any,
|
||||
instructions: 'You are a helpful assistant. Be as concise as possible.',
|
||||
tools: createMastraTools(searchTool)
|
||||
})
|
||||
|
||||
const res = await exampleAgent.generate(
|
||||
'${prompt}'
|
||||
)
|
||||
|
||||
console.log(res.text)`.trim(),
|
||||
lang: 'ts'
|
||||
}
|
||||
|
||||
case 'firebase-genkit':
|
||||
return {
|
||||
code: `
|
||||
import { createGenkitTools } from '@agentic/genkit'
|
||||
import { AgenticToolClient } from '@agentic/platform-tool-client'
|
||||
import { genkit } from 'genkit'
|
||||
import { gpt4oMini, openAI } from 'genkitx-openai'
|
||||
|
||||
const searchTool = await AgenticToolClient.fromIdentifier('${identifier}')
|
||||
|
||||
const ai = genkit({
|
||||
plugins: [openAI()]
|
||||
})
|
||||
|
||||
const result = await ai.generate({
|
||||
model: gpt4oMini,
|
||||
tools: createGenkitTools(ai, searchTool),
|
||||
prompt: '${prompt}'
|
||||
})
|
||||
|
||||
console.log(result)`.trim(),
|
||||
lang: 'ts'
|
||||
}
|
||||
|
||||
case 'xsai':
|
||||
return {
|
||||
code: `
|
||||
import { AgenticToolClient } from '@agentic/platform-tool-client'
|
||||
import { createXSAITools } from '@agentic/xsai'
|
||||
import { generateText } from 'xsai'
|
||||
|
||||
const searchTool = await AgenticToolClient.fromIdentifier('${identifier}')
|
||||
|
||||
const result = await generateText({
|
||||
apiKey: process.env.OPENAI_API_KEY!,
|
||||
baseURL: 'https://api.openai.com/v1/',
|
||||
model: 'gpt-4o-mini',
|
||||
tools: await createXSAITools(searchTool),
|
||||
toolChoice: 'required',
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: '${prompt}'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
console.log(JSON.stringify(result, null, 2))`.trim(),
|
||||
lang: 'ts'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// export function getCodeForPythonFrameworkConfig({
|
||||
// config,
|
||||
// project,
|
||||
// deployment,
|
||||
// tool
|
||||
// }: {
|
||||
// config: DeveloperConfig
|
||||
// project: Project
|
||||
// deployment: Deployment
|
||||
// identifier: string
|
||||
// tool?: string
|
||||
// }): string {
|
||||
// return ''
|
||||
// }
|
||||
export function getCodeForPythonFrameworkConfig(_opts: {
|
||||
config: DeveloperConfig
|
||||
project: Project
|
||||
deployment: Deployment
|
||||
identifier: string
|
||||
tool?: string
|
||||
}): CodeSnippet {
|
||||
return {
|
||||
code: 'Python SDK is coming soon. For now, use the MCP or HTTP examples',
|
||||
lang: 'md'
|
||||
}
|
||||
}
|
||||
|
||||
export function getCodeForHTTPConfig({
|
||||
config,
|
||||
|
@ -197,7 +364,7 @@ export function getCodeForHTTPConfig({
|
|||
deployment: Deployment
|
||||
identifier: string
|
||||
tool?: string
|
||||
}): string {
|
||||
}): CodeSnippet {
|
||||
tool ??= deployment.tools[0]?.name
|
||||
assert(tool, 'tool is required')
|
||||
// TODO: need a way of getting example tool args
|
||||
|
@ -206,9 +373,15 @@ export function getCodeForHTTPConfig({
|
|||
|
||||
switch (config.httpTarget) {
|
||||
case 'curl':
|
||||
return `curl -X POST -H "Content-Type: application/json" -d '{"query": "example google search"}' ${url}`
|
||||
return {
|
||||
code: `curl -X POST -H "Content-Type: application/json" -d '{"query": "example google search"}' ${url}`,
|
||||
lang: 'bash'
|
||||
}
|
||||
|
||||
case 'httpie':
|
||||
return `http -j ${url} query='example google search'`
|
||||
return {
|
||||
code: `http -j ${url} query='example google search'`,
|
||||
lang: 'bash'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,12 @@ export class AgenticToolClient extends AIFunctionsProvider {
|
|||
return this._functions
|
||||
}
|
||||
|
||||
async callTool(toolName: string, args: string | Record<string, any>) {
|
||||
const tool = this.functions.get(toolName)
|
||||
assert(tool, `Tool "${toolName}" not found`)
|
||||
return tool(typeof args === 'string' ? args : JSON.stringify(args))
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an Agentic tool client from a project or deployment identifier.
|
||||
*
|
||||
|
@ -84,8 +90,6 @@ export class AgenticToolClient extends AIFunctionsProvider {
|
|||
* @example
|
||||
* ```ts
|
||||
* const searchTool = await AgenticToolClient.fromIdentifier('@agentic/search')
|
||||
* const searchToolV1 = await AgenticToolClient.fromIdentifier('@agentic/search@v1.0.0')
|
||||
* const searchToolLatest = await AgenticToolClient.fromIdentifier('@agentic/search@latest')
|
||||
* ```
|
||||
*/
|
||||
static async fromIdentifier(
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
- consider using [neon serverless driver](https://orm.drizzle.team/docs/connect-neon) for production
|
||||
- can this also be used locally?
|
||||
- may need to update our `drizzle-orm` fork
|
||||
- simplify `AgenticToolClient` and only require one package per TS LLM SDK
|
||||
- `createAISDKToolsFromIdentifier(projectIdentifier)`
|
||||
|
||||
## TODO: Post-MVP
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue