kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
chore: improve claude.md
rodzic
c4b353d371
commit
449e927bb2
23
CLAUDE.md
23
CLAUDE.md
|
@ -12,7 +12,7 @@ The platform consists of:
|
|||
|
||||
- **API Service** (`apps/api/`) - Internal platform API with authentication, billing, and resource management
|
||||
- **Gateway Service** (`apps/gateway/`) - Cloudflare Worker that proxies requests to origin MCP/OpenAPI services
|
||||
- **E2E Tests** (`apps/e2e/`) - End-to-end test suite for HTTP and MCP interfaces
|
||||
- **E2E Tests** (`apps/e2e/`) - End-to-end test suite for HTTP and MCP gateway requests
|
||||
- **Shared Packages** (`packages/`) - Common utilities, types, validators, and configuration
|
||||
|
||||
The gateway accepts requests at `https://gateway.agentic.so/deploymentIdentifier/toolName` for REST or `https://gateway.agentic.so/deploymentIdentifier/mcp` for MCP.
|
||||
|
@ -119,27 +119,30 @@ All packages must follow these `package.json` rules:
|
|||
- Use TypeScript's utility types (e.g., `Partial`, `Pick`, `Omit`) to manipulate existing types
|
||||
- Create custom types for complex data structures used throughout the application
|
||||
- If possible, avoid using `any`/`unknown` or casting values like `(value as any)` in TypeScript outside of test files e.g. `*.test.ts` or test fixtures e.g. `**/test-data.ts`.
|
||||
- Don't rely on `typeof`, `ReturnType<>`, `Awaited<>`, etc for complex type inference (it's ok for simple types)
|
||||
- Try not to rely on `typeof`, `ReturnType<>`, `Awaited<>`, etc for complex type inference (it's ok for simple types)
|
||||
- You can use `as const` as needed for better type inference
|
||||
- Functions should accept an object parameter instead of multiple parameters
|
||||
- Good examples:
|
||||
- GOOD examples:
|
||||
```ts
|
||||
function myFunction({ foo, bar }: { foo: boolean; bar: string }) {}
|
||||
function VideoPlayer({ sid }: { sid: string }) {}
|
||||
```
|
||||
- Bad examples:
|
||||
- BAD examples:
|
||||
```ts
|
||||
function myFunction(foo: boolean, bar: string, baz: number) {}
|
||||
```
|
||||
- Arguments should generally be destructured in the function definition, not the function body.
|
||||
- Good example:
|
||||
- GOOD example:
|
||||
```ts
|
||||
function myFunction({ foo, bar }: { foo: boolean; bar: string }) {}
|
||||
function exampleWithOptionalParams({
|
||||
foo = 'example'
|
||||
}: { foo?: string } = {}) {}
|
||||
```
|
||||
- Bad example:
|
||||
- BAD example:
|
||||
```ts
|
||||
function myFunction(args: { foo: boolean; bar: string }) {
|
||||
const { foo, bar } = args
|
||||
function myFunction(opts: { foo: boolean; bar: string }) {
|
||||
const { foo, bar } = opts
|
||||
}
|
||||
```
|
||||
- Zod should be used to parse untrusted data, but not for data that is trusted like function arguments
|
||||
|
@ -192,8 +195,8 @@ Comments should be used to document and explain code. They should complement the
|
|||
- **All unit tests should use Vitest**
|
||||
- DO NOT attempt to install or use other testing libraries like Jest
|
||||
- Test files should be named `[target].test.ts` and placed in the same directory as the code they are testing (NOT a separate directory)
|
||||
- Good example: `src/my-file.ts` and `src/my-file.test.ts`
|
||||
- Bad example: `src/my-file.ts` and `src/test/my-file.test.ts` or `test/my-file.test.ts` or `src/__tests__/my-file.test.ts`
|
||||
- GOOD example: `src/my-file.ts` and `src/my-file.test.ts`
|
||||
- BAD example: `src/my-file.ts` and `src/test/my-file.test.ts` or `test/my-file.test.ts` or `src/__tests__/my-file.test.ts`
|
||||
- Tests should be run with `pnpm test:unit`
|
||||
- You may use `any`/`unknown` in test files (such as `*.test.ts`) or test fixtures (like `**/test-data.ts`) to facilitate mocking or stubbing external modules or partial function arguments, referencing the usage guidelines in the TypeScript section.
|
||||
- Frontend react code does not need unit tests
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
import { toolNameRe } from '@agentic/platform-validators'
|
||||
import { isToolNameAllowed, toolNameRe } from '@agentic/platform-validators'
|
||||
import { z } from '@hono/zod-openapi'
|
||||
|
||||
import { pricingPlanSlugSchema } from './pricing'
|
||||
import { rateLimitSchema } from './rate-limit'
|
||||
|
||||
// TODO: add more reserved tool names?
|
||||
// TODO: if we separate mcp endpoint from REST endpoint, we may be able to have
|
||||
// tools named `mcp`. would be nice not to impose a blacklist.
|
||||
const toolNameBlacklist = new Set(['mcp'])
|
||||
|
||||
/**
|
||||
* Agentic tool name.
|
||||
*
|
||||
* Follows OpenAI/Anthropic/Gemini function calling naming conventions.
|
||||
*
|
||||
* @example `"get_weather"`
|
||||
* @example `"searchGoogle"`
|
||||
* @example `"get_user_info2"`
|
||||
|
@ -21,9 +18,9 @@ export const toolNameSchema = z
|
|||
.nonempty()
|
||||
.regex(toolNameRe)
|
||||
.refine(
|
||||
(name) => !toolNameBlacklist.has(name),
|
||||
(name) => isToolNameAllowed(name),
|
||||
(name) => ({
|
||||
message: `Tool name is reserved: "${name}"`
|
||||
message: `Tool name "${name}" is reserved; please choose a different name.`
|
||||
})
|
||||
)
|
||||
.describe('Agentic tool name')
|
||||
|
|
|
@ -2,5 +2,6 @@ export * from './namespace-blacklist'
|
|||
export * from './parse-deployment-identifier'
|
||||
export * from './parse-project-identifier'
|
||||
export * from './parse-tool-identifier'
|
||||
export * from './tool-name-blacklist'
|
||||
export type * from './types'
|
||||
export * from './validators'
|
||||
|
|
|
@ -2,6 +2,7 @@ import { expect, test } from 'vitest'
|
|||
|
||||
import {
|
||||
isNamespaceAllowed,
|
||||
isToolNameAllowed,
|
||||
isValidDeploymentHash,
|
||||
isValidDeploymentIdentifier,
|
||||
isValidEmail,
|
||||
|
@ -177,3 +178,13 @@ test('isValidToolName failure', () => {
|
|||
)
|
||||
).toBe(false)
|
||||
})
|
||||
|
||||
test('isToolNameAllowed', () => {
|
||||
expect(isToolNameAllowed('foo')).toBe(true)
|
||||
expect(isToolNameAllowed('tool_name')).toBe(true)
|
||||
expect(isToolNameAllowed('searchGoogle')).toBe(true)
|
||||
expect(isToolNameAllowed('mcp')).toBe(false)
|
||||
expect(isToolNameAllowed('sse')).toBe(false)
|
||||
expect(isToolNameAllowed()).toBe(false)
|
||||
expect(isToolNameAllowed('')).toBe(false)
|
||||
})
|
||||
|
|
|
@ -5,6 +5,7 @@ import type { ParseIdentifierOptions } from './types'
|
|||
import { namespaceBlacklist } from './namespace-blacklist'
|
||||
import { parseDeploymentIdentifier } from './parse-deployment-identifier'
|
||||
import { parseProjectIdentifier } from './parse-project-identifier'
|
||||
import { toolNameBlacklist } from './tool-name-blacklist'
|
||||
|
||||
export const namespaceRe = /^[a-z0-9-]{1,256}$/
|
||||
export const passwordRe = /^.{3,1024}$/
|
||||
|
@ -72,6 +73,10 @@ export function isValidToolName(value?: string): boolean {
|
|||
return !!value && toolNameRe.test(value)
|
||||
}
|
||||
|
||||
export function isToolNameAllowed(value?: string): boolean {
|
||||
return !!value && isValidToolName(value) && !toolNameBlacklist.has(value)
|
||||
}
|
||||
|
||||
export function isValidCuid(value?: string): boolean {
|
||||
return !!value && isCuid(value)
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
## API Gateway
|
||||
|
||||
- **REST**: `GET/POST` `https://gateway.agentic.so/deploymentIdentifier/toolName`
|
||||
- **MCP**: `https://gateway.agentic.so/deploymentIdentifier/mcp`
|
||||
- **MCP**: `https://gateway.agentic.so/@{username}/{project-name}/mcp`
|
||||
- **HTTP**: `GET/POST` `https://gateway.agentic.so/@{username}/{project-name}/{tool-name}`
|
||||
|
||||
## TODO: MVP
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
|||
- oauth flow
|
||||
- https://docs.scalekit.com/guides/mcp/oauth
|
||||
- **test usage tracking and reporting**
|
||||
- disallow `mcp` and `sse` as tool names or figure out a different workaround
|
||||
- docs
|
||||
- main readme
|
||||
- sub readmes
|
||||
|
|
Ładowanie…
Reference in New Issue