feat: improve example-usage

pull/715/head
Travis Fischer 2025-06-24 20:41:55 -05:00
rodzic 7b5f7e8f97
commit 591a5d65c3
5 zmienionych plików z 149 dodań i 61 usunięć

Wyświetl plik

@ -7,6 +7,7 @@ import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { AgenticProvider } from '@/components/agentic-provider'
import { PostHogProvider } from '@/components/posthog-provider'
import { ThemeProvider } from '@/components/theme-provider'
import { TooltipProvider } from '@/components/ui/tooltip'
import { queryClient } from '@/lib/query-client'
export default function Providers({ children }: { children: React.ReactNode }) {
@ -19,7 +20,7 @@ export default function Providers({ children }: { children: React.ReactNode }) {
disableTransitionOnChange
>
<QueryClientProvider client={queryClient}>
{children}
<TooltipProvider>{children}</TooltipProvider>
<ReactQueryDevtools />
</QueryClientProvider>

Wyświetl plik

@ -11,6 +11,11 @@ import {
import { jsx, jsxs } from 'react/jsx-runtime'
import { type BundledLanguage, codeToHast } from 'shiki/bundle/web'
import {
Tooltip,
TooltipContent,
TooltipTrigger
} from '@/components/ui/tooltip'
import { toastError } from '@/lib/notifications'
import { cn } from '@/lib/utils'
@ -71,7 +76,7 @@ export function CodeBlock({
code,
lang,
theme,
className: 'rounded-sm w-full text-wrap p-4 text-sm'
className: 'w-full text-wrap p-4 text-sm'
}).then(setNodes)
}, [code, lang, theme])
@ -102,19 +107,34 @@ export function CodeBlock({
})()
}, [code, timeoutRef])
const numNewLines = code.split('\n').length
return (
<div className={cn('relative group rounded-sm w-full', className)}>
<div
className={cn('relative group rounded-sm w-full shadow-sm', 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>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant='outline'
className={cn(
'absolute right-4 px-2.5! opacity-0 group-hover:opacity-100 group-hover:duration-0 transition-opacity duration-150',
numNewLines <= 1 ? 'top-[50%] translate-y-[-50%]' : 'top-4'
)}
onClick={onCopy}
>
{isCopied ? <CheckIcon /> : <CopyIcon />}
</Button>
</TooltipTrigger>
<TooltipContent side='bottom'>
{isCopied ? <span>Copied</span> : <span>Copy to clipboard</span>}
</TooltipContent>
</Tooltip>
</>
) : (
<LoadingIndicator />

Wyświetl plik

@ -8,7 +8,6 @@ import { Button } from '@/components/ui/button'
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger
} from '@/components/ui/tooltip'
import { cn } from '@/lib/utils'
@ -17,27 +16,23 @@ export function DarkModeToggle({ className }: { className?: string }) {
const { setTheme, resolvedTheme } = useTheme()
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant='outline'
size='icon'
className={cn('cursor-pointer', className)}
onClick={() =>
setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')
}
>
<Sun className='h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0' />
<Moon className='absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100' />
<span className='sr-only'>Toggle theme</span>
</Button>
</TooltipTrigger>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant='outline'
size='icon'
className={cn('cursor-pointer', className)}
onClick={() => setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')}
>
<Sun className='h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0' />
<Moon className='absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100' />
<span className='sr-only'>Toggle theme</span>
</Button>
</TooltipTrigger>
<TooltipContent>
<span>Toggle dark mode</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<TooltipContent>
<span>Toggle dark mode</span>
</TooltipContent>
</Tooltip>
)
}

Wyświetl plik

@ -41,6 +41,7 @@ export function ExampleUsage() {
// 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'
const prompt = 'What is the latest news about AI?'
// Load the public project
const {
@ -98,7 +99,8 @@ export function ExampleUsage() {
config,
project,
deployment,
identifier: projectIdentifier
identifier: projectIdentifier,
prompt
})
return (

Wyświetl plik

@ -27,6 +27,7 @@ export type HTTPTarget = (typeof httpTargets)[number]
export const mcpClientTargetLabels = {
url: 'MCP Server URL',
'claude-desktop': 'Claude Desktop',
chatgpt: 'ChatGPT',
raycast: 'Raycast',
cursor: 'Cursor',
windsurf: 'Windsurf',
@ -82,22 +83,30 @@ export type CodeSnippet = {
// install?: string // TODO
}
export function getCodeForDeveloperConfig(opts: {
export type GetCodeForDeveloperConfigOpts = {
config: DeveloperConfig
project: Project
deployment: Deployment
identifier: string
prompt: string
tool?: string
}): CodeSnippet {
}
export function getCodeForDeveloperConfig(
opts: GetCodeForDeveloperConfigOpts
): CodeSnippet {
const { config } = opts
switch (config.target) {
case 'mcp':
return getCodeForMCPClientConfig(opts)
case 'typescript':
return getCodeForTSFrameworkConfig(opts)
case 'python':
return getCodeForPythonFrameworkConfig(opts)
case 'http':
return getCodeForHTTPConfig(opts)
}
@ -105,11 +114,10 @@ export function getCodeForDeveloperConfig(opts: {
export function getCodeForMCPClientConfig({
identifier
}: {
identifier: string
}): CodeSnippet {
}: GetCodeForDeveloperConfigOpts): CodeSnippet {
const mcpUrl = `${gatewayBaseUrl}/${identifier}/mcp`
return {
code: `${gatewayBaseUrl}/${identifier}/mcp`,
code: mcpUrl,
lang: 'bash'
}
}
@ -117,12 +125,8 @@ export function getCodeForMCPClientConfig({
export function getCodeForTSFrameworkConfig({
config,
identifier,
prompt = 'What is the latest news about AI?'
}: {
config: DeveloperConfig
identifier: string
prompt?: string
}): CodeSnippet {
prompt
}: GetCodeForDeveloperConfigOpts): CodeSnippet {
switch (config.tsFrameworkTarget) {
case 'ai':
return {
@ -341,16 +345,87 @@ console.log(JSON.stringify(result, null, 2))`.trim(),
}
}
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 getCodeForPythonFrameworkConfig({
config,
identifier,
prompt
}: GetCodeForDeveloperConfigOpts): CodeSnippet {
const mcpUrl = `${gatewayBaseUrl}/${identifier}/mcp`
switch (config.pyFrameworkTarget) {
case 'openai':
return {
code: `
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-4.1",
tools=[
{
"type": "mcp",
"server_label": "${identifier}",
"server_url": "${mcpUrl}",
"require_approval": "never",
},
],
input="${prompt}",
)
print(response.output_text)
`.trim(),
lang: 'py'
}
case 'langchain':
return {
code: `
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent
client = MultiServerMCPClient(
{
"search": {
"url": "${mcpUrl}",
"transport": "streamable_http",
}
}
)
tools = await client.get_tools()
agent = create_react_agent(
"anthropic:claude-3-7-sonnet-latest",
tools
)
response = await agent.ainvoke(
{"messages": [{"role": "user", "content": "${prompt}"}]}
)`.trim(),
lang: 'py'
}
case 'llamaindex':
return {
code: `
from llama_index.llms.openai import OpenAI
from llama_index.core.agent.workflow import ReActAgent
from llama_index.core.workflow import Context
from llama_index.tools.mcp import (
get_tools_from_mcp_url,
aget_tools_from_mcp_url,
)
tools = await aget_tools_from_mcp_url("${mcpUrl}")
llm = OpenAI(model="gpt-4o-mini")
agent = ReActAgent(tools=tools, llm=llm)
ctx = Context(agent)
response = await agent.run("${prompt}", ctx=ctx)
print(str(response))
`.trim(),
lang: 'py'
}
}
}
@ -359,12 +434,7 @@ export function getCodeForHTTPConfig({
identifier,
deployment,
tool
}: {
config: DeveloperConfig
deployment: Deployment
identifier: string
tool?: string
}): CodeSnippet {
}: GetCodeForDeveloperConfigOpts): CodeSnippet {
tool ??= deployment.tools[0]?.name
assert(tool, 'tool is required')
// TODO: need a way of getting example tool args