feat: add @agentic/search to http e2e fixtures

pull/715/head
Travis Fischer 2025-06-25 02:30:22 -05:00
rodzic 34d73481d7
commit 4a49cd3e42
11 zmienionych plików z 91 dodań i 31 usunięć

Wyświetl plik

@ -21,6 +21,11 @@ STRIPE_WEBHOOK_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
RESEND_API_KEY=
# Used to make admin API calls from the API gateway
AGENTIC_ADMIN_API_KEY=
RESEND_API_KEY=
# Used to simplify recreating the demo `@agentic/search` project during
# development while we're frequently resetting the database
AGENTIC_SEARCH_PROXY_SECRET=

Wyświetl plik

@ -84,6 +84,13 @@ export function registerV1CreateDeployment(
user.username === 'agentic'
)
// Used to simplify recreating the demo `@agentic/search` project during
// development while we're frequently resetting the database
const secret =
projectIdentifier === '@agentic/search'
? env.AGENTIC_SEARCH_PROXY_SECRET
: await sha256()
// Upsert the project if it doesn't already exist
// The typecast is necessary here because we're not populating the
// lastPublishedDeployment, but that's fine because it's a new project
@ -98,7 +105,7 @@ export function registerV1CreateDeployment(
userId: user.id,
teamId: teamMember?.teamId,
private: isPrivate,
_secret: await sha256()
_secret: secret
})
.returning()
)[0] as typeof project

Wyświetl plik

@ -55,12 +55,8 @@ export function registerV1CreateProject(
const teamMember = c.get('teamMember')
const namespace = teamMember ? teamMember.teamSlug : user.username
const identifier = `@${namespace}/${body.name}`
const parsedProjectIdentifier = parseProjectIdentifier(identifier)
assert(
parsedProjectIdentifier,
400,
`Invalid project identifier "${identifier}"`
)
const { projectIdentifier, projectNamespace, projectName } =
parseProjectIdentifier(identifier)
// Used for testing e2e fixtures in the development marketplace
const isPrivate = !(
@ -68,17 +64,24 @@ export function registerV1CreateProject(
user.username === 'agentic'
)
// Used to simplify recreating the demo `@agentic/search` project during
// development while we're frequently resetting the database
const secret =
projectIdentifier === '@agentic/search'
? env.AGENTIC_SEARCH_PROXY_SECRET
: await sha256()
const [project] = await db
.insert(schema.projects)
.values({
...body,
identifier: parsedProjectIdentifier.projectIdentifier,
namespace: parsedProjectIdentifier.projectNamespace,
name: parsedProjectIdentifier.projectName,
identifier: projectIdentifier,
namespace: projectNamespace,
name: projectName,
teamId: teamMember?.teamId,
userId: user.id,
private: isPrivate,
_secret: await sha256()
_secret: secret
})
.returning()
assert(project, 500, `Failed to create project "${body.name}"`)

Wyświetl plik

@ -15,7 +15,7 @@ export const envSchema = baseEnvSchema
JWT_SECRET: z.string().nonempty(),
PORT: z.number().default(3001),
PORT: z.coerce.number().default(3001),
STRIPE_SECRET_KEY: z.string().nonempty(),
STRIPE_WEBHOOK_SECRET: z.string().nonempty(),
@ -23,9 +23,14 @@ export const envSchema = baseEnvSchema
GITHUB_CLIENT_ID: z.string().nonempty(),
GITHUB_CLIENT_SECRET: z.string().nonempty(),
RESEND_API_KEY: z.string().nonempty(),
// Used to make admin API calls from the API gateway
AGENTIC_ADMIN_API_KEY: z.string().nonempty(),
RESEND_API_KEY: z.string().nonempty()
// Used to simplify recreating the demo `@agentic/search` project during
// development while we're frequently resetting the database
AGENTIC_SEARCH_PROXY_SECRET: z.string().nonempty()
})
.strip()
export type RawEnv = z.infer<typeof envSchema>

Wyświetl plik

@ -137,8 +137,8 @@ for (const [i, fixtureSuite] of fixtureSuites.entries()) {
if (debugFixture) {
console.log(
`${repeatIterationPrefix}${fixtureName} => ${res.status}`,
{
body,
{
headers: Object.fromEntries(res.headers.entries())
}
)

Wyświetl plik

@ -716,5 +716,24 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
}
}
]
},
{
title: 'HTTP => Production MCP origin "search" tool',
// NOTE: this one actually hits a production service and costs a small
// amount of $ per request.
fixtures: [
{
path: '@agentic/search/search',
request: {
method: 'POST',
json: {
query: 'latest ai news'
}
},
response: {
snapshot: false
}
}
]
}
]

Wyświetl plik

@ -18,7 +18,6 @@
},
"dependencies": {
"@agentic/platform": "workspace:*",
"@agentic/platform-core": "workspace:*",
"@agentic/serper": "catalog:",
"@hono/mcp": "catalog:",
"@modelcontextprotocol/sdk": "catalog:",

Wyświetl plik

@ -1,4 +1,3 @@
import { assert } from '@agentic/platform-core'
import { SerperClient } from '@agentic/serper'
import { StreamableHTTPTransport } from '@hono/mcp'
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
@ -59,21 +58,42 @@ export default {
.optional()
.describe('Type of Google search to perform')
}).shape,
outputSchema: z.object({}).passthrough().shape
outputSchema: z
.object({
results: z.any(),
answerBox: z.any().optional(),
knowledgeGraph: z.any().optional(),
images: z.any().optional(),
videos: z.any().optional(),
places: z.any().optional(),
news: z.any().optional(),
shopping: z.any().optional()
})
.passthrough().shape
},
async (args, { _meta }) => {
console.log('search call', {
args,
_meta
})
// Make sure the request is coming from Agentic
assert(
(_meta?.agentic as any)?.agenticProxySecret ===
parsedEnv.AGENTIC_PROXY_SECRET,
400,
'Invalid request'
)
if (
(_meta?.agentic as any)?.agenticProxySecret !==
parsedEnv.AGENTIC_PROXY_SECRET
) {
return {
content: [],
structuredContent: {
error: 'Invalid request'
}
}
}
const result: any = await serper!.search({
q: args.query,
num: args.num,
type: args.type
num: args.num ?? 5,
type: args.type ?? 'search'
})
// Simplify search results to optimize for LLM usage
@ -83,6 +103,7 @@ export default {
delete result.peopleAlsoAsk
delete result.searchParameters
delete result.credits
delete result.relatedSearches
return {
content: [],

Wyświetl plik

@ -8,5 +8,9 @@
"compatibility_date": "2025-05-25",
"compatibility_flags": ["nodejs_compat"],
"placement": { "mode": "smart" },
"upload_source_maps": true
"upload_source_maps": true,
"observability": {
"enabled": true,
"head_sampling_rate": 1
}
}

Wyświetl plik

@ -834,9 +834,6 @@ importers:
'@agentic/platform':
specifier: workspace:*
version: link:../../packages/platform
'@agentic/platform-core':
specifier: workspace:*
version: link:../../packages/core
'@agentic/serper':
specifier: 'catalog:'
version: 7.6.7(zod@3.25.67)

Wyświetl plik

@ -38,7 +38,7 @@
- merge with current agentic repo
- publish packages to npm
- api
- deploy to prod
- **deploy to prod**
- database
- consider using [neon serverless driver](https://orm.drizzle.team/docs/connect-neon) for production
- can this also be used locally?