Skip to content

Commit fb84cfe

Browse files
feat(api): api update
1 parent cbc2d23 commit fb84cfe

File tree

229 files changed

+2904
-1209
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

229 files changed

+2904
-1209
lines changed

.github/workflows/ci.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ on:
77
- 'integrated/**'
88
- 'stl-preview-head/**'
99
- 'stl-preview-base/**'
10+
pull_request:
11+
branches-ignore:
12+
- 'stl-preview-head/**'
13+
- 'stl-preview-base/**'
1014

1115
jobs:
1216
lint:
1317
timeout-minutes: 10
1418
name: lint
1519
runs-on: ${{ github.repository == 'stainless-sdks/hanzo-ai-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
20+
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
1621
steps:
1722
- uses: actions/checkout@v4
1823

@@ -31,6 +36,7 @@ jobs:
3136
timeout-minutes: 5
3237
name: build
3338
runs-on: ${{ github.repository == 'stainless-sdks/hanzo-ai-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
39+
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
3440
permissions:
3541
contents: read
3642
id-token: write
@@ -66,6 +72,7 @@ jobs:
6672
timeout-minutes: 10
6773
name: test
6874
runs-on: ${{ github.repository == 'stainless-sdks/hanzo-ai-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
75+
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
6976
steps:
7077
- uses: actions/checkout@v4
7178

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 188
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hanzo-industries-inc%2Fhanzo-ai-ec4be99f95dc46e9442eb60f233b2bff271d6f5bf57d7c61a52bc4804f55bbd1.yml
3-
openapi_spec_hash: 87bc62c36bb6028ffd1f3e54a2809099
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/hanzo-industries-inc%2Fhanzo-ai-2d6e1036fb1eea7e95cafc281141ead9ef77796e43711b17edccaab67c5e791a.yml
3+
openapi_spec_hash: 12501774d0127be4ec1812d613a58e97
44
config_hash: 830747463ff4d018b5633ce511e88558

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Hanzo TypeScript API Library
22

3-
[![NPM version](https://img.shields.io/npm/v/hanzoai.svg)](https://npmjs.org/package/hanzoai) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/hanzoai)
3+
[![NPM version](<https://img.shields.io/npm/v/hanzoai.svg?label=npm%20(stable)>)](https://npmjs.org/package/hanzoai) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/hanzoai)
44

55
This library provides convenient access to the Hanzo REST API from server-side TypeScript or JavaScript.
66

@@ -251,9 +251,8 @@ parameter. This library doesn't validate at runtime that the request matches the
251251
send will be sent as-is.
252252

253253
```ts
254-
client.foo.create({
255-
foo: 'my_param',
256-
bar: 12,
254+
client.getHome({
255+
// ...
257256
// @ts-expect-error baz is not yet public
258257
baz: 'undocumented option',
259258
});

bin/check-release-environment

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
errors=()
44

55
if [ -z "${NPM_TOKEN}" ]; then
6-
errors+=("The HANZO_NPM_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets")
6+
errors+=("The NPM_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets")
77
fi
88

99
lenErrors=${#errors[@]}

bin/publish-npm

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,35 @@ npm config set '//registry.npmjs.org/:_authToken' "$NPM_TOKEN"
77
yarn build
88
cd dist
99

10+
# Get package name and version from package.json
11+
PACKAGE_NAME="$(jq -r -e '.name' ./package.json)"
12+
VERSION="$(jq -r -e '.version' ./package.json)"
13+
1014
# Get latest version from npm
1115
#
12-
# If the package doesn't exist, yarn will return
13-
# {"type":"error","data":"Received invalid response from npm."}
14-
# where .data.version doesn't exist so LAST_VERSION will be an empty string.
15-
LAST_VERSION="$(yarn info --json 2> /dev/null | jq -r '.data.version')"
16-
17-
# Get current version from package.json
18-
VERSION="$(node -p "require('./package.json').version")"
16+
# If the package doesn't exist, npm will return:
17+
# {
18+
# "error": {
19+
# "code": "E404",
20+
# "summary": "Unpublished on 2025-06-05T09:54:53.528Z",
21+
# "detail": "'the_package' is not in this registry..."
22+
# }
23+
# }
24+
NPM_INFO="$(npm view "$PACKAGE_NAME" version --json 2>/dev/null || true)"
25+
26+
# Check if we got an E404 error
27+
if echo "$NPM_INFO" | jq -e '.error.code == "E404"' > /dev/null 2>&1; then
28+
# Package doesn't exist yet, no last version
29+
LAST_VERSION=""
30+
elif echo "$NPM_INFO" | jq -e '.error' > /dev/null 2>&1; then
31+
# Report other errors
32+
echo "ERROR: npm returned unexpected data:"
33+
echo "$NPM_INFO"
34+
exit 1
35+
else
36+
# Success - get the version
37+
LAST_VERSION=$(echo "$NPM_INFO" | jq -r '.') # strip quotes
38+
fi
1939

2040
# Check if current version is pre-release (e.g. alpha / beta / rc)
2141
CURRENT_IS_PRERELEASE=false

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
"@swc/jest": "^0.2.29",
3131
"@types/jest": "^29.4.0",
3232
"@types/node": "^20.17.6",
33-
"typescript-eslint": "8.31.1",
3433
"@typescript-eslint/eslint-plugin": "8.31.1",
3534
"@typescript-eslint/parser": "8.31.1",
3635
"eslint": "^9.20.1",
@@ -42,9 +41,10 @@
4241
"publint": "^0.2.12",
4342
"ts-jest": "^29.1.0",
4443
"ts-node": "^10.5.0",
45-
"tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz",
44+
"tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.8/tsc-multi.tgz",
4645
"tsconfig-paths": "^4.0.0",
47-
"typescript": "5.8.3"
46+
"typescript": "5.8.3",
47+
"typescript-eslint": "8.31.1"
4848
},
4949
"imports": {
5050
"hanzoai": ".",

packages/mcp-server/build

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,10 @@ PKG_JSON_PATH=../../packages/mcp-server/package.json node ../../scripts/utils/ma
2323
node scripts/postprocess-dist-package-json.cjs
2424

2525
# build to .js/.mjs/.d.ts files
26-
npm exec tsc-multi
26+
./node_modules/.bin/tsc-multi
2727

2828
cp tsconfig.dist-src.json dist/src/tsconfig.json
2929

30-
# Add proper Node.js shebang to the top of the file
31-
sed -i.bak '1s;^;#!/usr/bin/env node\n;' dist/index.js
32-
rm dist/index.js.bak
33-
3430
chmod +x dist/index.js
3531

3632
DIST_PATH=./dist PKG_IMPORT_PATH=hanzoai-mcp/ node ../../scripts/utils/postprocess-files.cjs

packages/mcp-server/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@
2828
},
2929
"dependencies": {
3030
"hanzoai": "file:../../dist/",
31-
"@modelcontextprotocol/sdk": "^1.6.1",
31+
"@modelcontextprotocol/sdk": "^1.11.5",
32+
"jq-web": "https://github.com/stainless-api/jq-web/releases/download/v0.8.2/jq-web.tar.gz",
3233
"yargs": "^17.7.2",
3334
"@cloudflare/cabidela": "^0.2.4",
34-
"zod": "^3.24.4",
35+
"zod": "^3.25.20",
3536
"zod-to-json-schema": "^3.24.5"
3637
},
3738
"bin": {
@@ -49,7 +50,7 @@
4950
"ts-jest": "^29.1.0",
5051
"ts-morph": "^19.0.0",
5152
"ts-node": "^10.5.0",
52-
"tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz",
53+
"tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.8/tsc-multi.tgz",
5354
"tsconfig-paths": "^4.0.0",
5455
"typescript": "5.8.3"
5556
},

packages/mcp-server/src/compat.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,46 @@ export const defaultClientCapabilities: ClientCapabilities = {
1919
toolNameLength: undefined,
2020
};
2121

22+
export type ClientType = 'openai-agents' | 'claude' | 'claude-code' | 'cursor';
23+
24+
// Client presets for compatibility
25+
// Note that these could change over time as models get better, so this is
26+
// a best effort.
27+
export const knownClients: Record<ClientType, ClientCapabilities> = {
28+
'openai-agents': {
29+
topLevelUnions: false,
30+
validJson: true,
31+
refs: true,
32+
unions: true,
33+
formats: true,
34+
toolNameLength: undefined,
35+
},
36+
claude: {
37+
topLevelUnions: true,
38+
validJson: false,
39+
refs: true,
40+
unions: true,
41+
formats: true,
42+
toolNameLength: undefined,
43+
},
44+
'claude-code': {
45+
topLevelUnions: false,
46+
validJson: true,
47+
refs: true,
48+
unions: true,
49+
formats: true,
50+
toolNameLength: undefined,
51+
},
52+
cursor: {
53+
topLevelUnions: false,
54+
validJson: true,
55+
refs: false,
56+
unions: false,
57+
formats: false,
58+
toolNameLength: 50,
59+
},
60+
};
61+
2262
/**
2363
* Attempts to parse strings into JSON objects
2464
*/

packages/mcp-server/src/dynamic-tools.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Hanzo from 'hanzoai';
2-
import { Endpoint } from './tools';
2+
import { Endpoint, asTextContentResult, ToolCallResult } from './tools/types';
33
import { zodToJsonSchema } from 'zod-to-json-schema';
44
import { z } from 'zod';
55
import { Cabidela } from '@cloudflare/cabidela';
@@ -41,7 +41,7 @@ export function dynamicTools(endpoints: Endpoint[]): Endpoint[] {
4141
description: 'List or search for all endpoints in the Hanzo TypeScript API',
4242
inputSchema: zodToInputSchema(listEndpointsSchema),
4343
},
44-
handler: async (client: Hanzo, args: Record<string, unknown> | undefined) => {
44+
handler: async (client: Hanzo, args: Record<string, unknown> | undefined): Promise<ToolCallResult> => {
4545
const query = args && listEndpointsSchema.parse(args).search_query?.trim();
4646

4747
const filteredEndpoints =
@@ -58,15 +58,15 @@ export function dynamicTools(endpoints: Endpoint[]): Endpoint[] {
5858
})
5959
: endpoints;
6060

61-
return {
61+
return asTextContentResult({
6262
tools: filteredEndpoints.map(({ tool, metadata }) => ({
6363
name: tool.name,
6464
description: tool.description,
6565
resource: metadata.resource,
6666
operation: metadata.operation,
6767
tags: metadata.tags,
6868
})),
69-
};
69+
});
7070
},
7171
};
7272

@@ -95,7 +95,7 @@ export function dynamicTools(endpoints: Endpoint[]): Endpoint[] {
9595
if (!endpoint) {
9696
throw new Error(`Endpoint ${endpointName} not found`);
9797
}
98-
return endpoint.tool;
98+
return asTextContentResult(endpoint.tool);
9999
},
100100
};
101101

@@ -120,7 +120,7 @@ export function dynamicTools(endpoints: Endpoint[]): Endpoint[] {
120120
'Invoke an endpoint in the Hanzo TypeScript API. Note: use the `list_api_endpoints` tool to get the list of endpoints and `get_api_endpoint_schema` tool to get the schema for an endpoint.',
121121
inputSchema: zodToInputSchema(invokeEndpointSchema),
122122
},
123-
handler: async (client: Hanzo, args: Record<string, unknown> | undefined) => {
123+
handler: async (client: Hanzo, args: Record<string, unknown> | undefined): Promise<ToolCallResult> => {
124124
if (!args) {
125125
throw new Error('No endpoint provided');
126126
}
@@ -145,7 +145,7 @@ export function dynamicTools(endpoints: Endpoint[]): Endpoint[] {
145145
throw new Error(`Invalid arguments for endpoint ${endpoint_name}:\n${error}`);
146146
}
147147

148-
return endpoint.handler(client, endpointArgs);
148+
return await endpoint.handler(client, endpointArgs);
149149
},
150150
};
151151

0 commit comments

Comments
 (0)