Skip to content

Commit

Permalink
fix(tools): openapi fixing and adding example
Browse files Browse the repository at this point in the history
Signed-off-by: Akihiko Kuroda <[email protected]>
  • Loading branch information
akihikokuroda committed Jan 13, 2025
1 parent 9295593 commit cf44945
Show file tree
Hide file tree
Showing 3 changed files with 381 additions and 1 deletion.
342 changes: 342 additions & 0 deletions examples/tools/github_schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,342 @@
{
"openapi": "3.1.0",
"info": {
"version": "1.1.4",
"title": "GitHub v3 REST API",
"description": "GitHub's v3 REST API.",
"license": {
"name": "MIT",
"url": "https://spdx.org/licenses/MIT"
},
"termsOfService": "https://docs.github.com/articles/github-terms-of-service",
"contact": {
"name": "Support",
"url": "https://support.github.com/contact?tags=dotcom-rest-api"
},
"x-github-plan": "api.github.com"
},
"servers": [
{
"url": "https://api.github.com"
}
],
"externalDocs": {
"description": "GitHub v3 REST API",
"url": "https://docs.github.com/rest/"
},
"paths": {
"/orgs/{org}": {
"get": {
"summary": "Get an organization",
"description": "Gets information about an organization.\n\nWhen the value of `two_factor_requirement_enabled` is `true`, the organization requires all members, billing managers, and outside collaborators to enable [two-factor authentication](https://docs.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/).\n\nTo see the full details about an organization, the authenticated user must be an organization owner.\n\nOAuth app tokens and personal access tokens (classic) need the `admin:org` scope to see the full details about an organization.\n\nTo see information about an organization's GitHub plan, GitHub Apps need the `Organization plan` permission.",
"tags": ["orgs"],
"operationId": "orgs/get",
"externalDocs": {
"description": "API method documentation",
"url": "https://docs.github.com/rest/orgs/orgs#get-an-organization"
},
"parameters": [
{
"name": "org",
"description": "The organization name. The name is not case sensitive.",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/organization-full"
},
"examples": {
"default-response": {
"$ref": "#/components/examples/organization-full"
}
}
}
}
},
"404": {
"$ref": "#/components/responses/not_found"
}
},
"x-github": {
"githubCloudOnly": false,
"enabledForGitHubApps": true,
"category": "orgs",
"subcategory": "orgs"
}
}
},
"/organizations": {
"get": {
"summary": "List organizations",
"description": "Lists all organizations, in the order that they were created.\n\n> [!NOTE]\n> Pagination is powered exclusively by the `since` parameter. Use the [Link header](https://docs.github.com/rest/guides/using-pagination-in-the-rest-api#using-link-headers) to get the URL for the next page of organizations.",
"tags": ["orgs"],
"operationId": "orgs/list",
"externalDocs": {
"description": "API method documentation",
"url": "https://docs.github.com/rest/orgs/orgs#list-organizations"
},
"parameters": [
{
"since-org": {
"name": "since",
"description": "An organization ID. Only return organizations with an ID greater than this ID.",
"in": "query",
"required": false,
"schema": {
"type": "integer"
}
}
},
{
"per-page": {
"name": "per_page",
"description": "The number of results per page (max 100). For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\"",
"in": "query",
"schema": {
"type": "integer",
"default": 30
}
}
}
],
"responses": {
"200": {
"description": "Response",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/organization-simple"
}
},
"examples": {
"default": {
"$ref": "#/components/examples/organization-simple-items"
}
}
}
},
"headers": {
"Link": {
"example": "<https://api.github.com/organizations?since=135>; rel=\"next\"",
"schema": {
"type": "string"
}
}
}
},
"304": {
"$ref": "#/components/responses/not_modified"
}
},
"x-github": {
"githubCloudOnly": false,
"enabledForGitHubApps": true,
"category": "orgs",
"subcategory": "orgs"
}
}
}
},
"components": {
"schemas": {
"organization-full": {
"title": "Organization Full",
"description": "Organization Full",
"type": "object",
"properties": {
"login": {
"type": "string",
"examples": ["github"]
},
"id": {
"type": "integer",
"examples": [1]
},
"node_id": {
"type": "string",
"examples": ["MDEyOk9yZ2FuaXphdGlvbjE="]
},
"url": {
"type": "string",
"format": "uri",
"examples": ["https://api.github.com/orgs/github"]
}
}
},
"organization-simple": {
"title": "Organization Simple",
"description": "A GitHub organization.",
"type": "object",
"properties": {
"login": {
"type": "string",
"examples": ["github"]
},
"id": {
"type": "integer",
"examples": [1]
},
"node_id": {
"type": "string",
"examples": ["MDEyOk9yZ2FuaXphdGlvbjE="]
},
"url": {
"type": "string",
"format": "uri",
"examples": ["https://api.github.com/orgs/github"]
},
"repos_url": {
"type": "string",
"format": "uri",
"examples": ["https://api.github.com/orgs/github/repos"]
},
"events_url": {
"type": "string",
"format": "uri",
"examples": ["https://api.github.com/orgs/github/events"]
},
"hooks_url": {
"type": "string",
"examples": ["https://api.github.com/orgs/github/hooks"]
},
"issues_url": {
"type": "string",
"examples": ["https://api.github.com/orgs/github/issues"]
},
"members_url": {
"type": "string",
"examples": ["https://api.github.com/orgs/github/members{/member}"]
},
"public_members_url": {
"type": "string",
"examples": ["https://api.github.com/orgs/github/public_members{/member}"]
},
"avatar_url": {
"type": "string",
"examples": ["https://github.com/images/error/octocat_happy.gif"]
},
"description": {
"type": ["string", "null"],
"examples": ["A great organization"]
}
},
"required": [
"login",
"url",
"id",
"node_id",
"repos_url",
"events_url",
"hooks_url",
"issues_url",
"members_url",
"public_members_url",
"avatar_url",
"description"
]
},
"basic-error": {
"title": "Basic Error",
"description": "Basic Error",
"type": "object",
"properties": {
"message": {
"type": "string"
},
"documentation_url": {
"type": "string"
},
"url": {
"type": "string"
},
"status": {
"type": "string"
}
}
}
},
"examples": {
"organization-full": {
"value": {
"login": "github",
"id": 1,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE=",
"url": "https://api.github.com/orgs/github"
}
},
"organization-simple-items": {
"value": [
{
"login": "github",
"id": 1,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE=",
"url": "https://api.github.com/orgs/github",
"repos_url": "https://api.github.com/orgs/github/repos",
"events_url": "https://api.github.com/orgs/github/events",
"hooks_url": "https://api.github.com/orgs/github/hooks",
"issues_url": "https://api.github.com/orgs/github/issues",
"members_url": "https://api.github.com/orgs/github/members{/member}",
"public_members_url": "https://api.github.com/orgs/github/public_members{/member}",
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"description": "A great organization"
}
]
}
},
"parameters": {
"org": {
"name": "org",
"description": "The organization name. The name is not case sensitive.",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
"since-org": {
"name": "since",
"description": "An organization ID. Only return organizations with an ID greater than this ID.",
"in": "query",
"required": false,
"schema": {
"type": "integer"
}
},
"per-page": {
"name": "per_page",
"description": "The number of results per page (max 100). For more information, see \"[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api).\"",
"in": "query",
"schema": {
"type": "integer",
"default": 30
}
}
},
"responses": {
"not_modified": {
"description": "Not modified"
},
"not_found": {
"description": "Resource not found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/basic-error"
}
}
}
}
}
}
}
36 changes: 36 additions & 0 deletions examples/tools/openapi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import "dotenv/config.js";
import { BeeAgent } from "bee-agent-framework/agents/bee/agent";
import { TokenMemory } from "bee-agent-framework/memory/tokenMemory";
import { OllamaChatLLM } from "bee-agent-framework/adapters/ollama/chat";
import { OpenAPITool } from "bee-agent-framework/tools/openapi";
import * as fs from "fs";

async function fetchSchema() {
try {
const fileContent = fs.readFileSync("examples/tools/github_schema.json", "utf-8");
return fileContent;
} catch (error) {
console.error("An error occurred:", error);
}
}
const spec = await fetchSchema();

const llm = new OllamaChatLLM({
modelId: "llama3.1", // llama3.1:70b for better performance
});

const agent = new BeeAgent({
llm,
memory: new TokenMemory({ llm }),
tools: [new OpenAPITool({ name: "Github API", description: "Github API", openApiSchema: spec })],
});

const response = await agent
.run({ prompt: 'How many repositories are in "i-am-bee" org?' })
.observe((emitter) => {
emitter.on("update", async ({ data, update, meta }) => {
console.log(`Agent (${update.key}) 🤖 : `, update.value);
});
});

console.log(`Agent 🤖 : `, response.result.text);
4 changes: 3 additions & 1 deletion src/tools/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export interface OpenAPIToolOptions extends BaseToolOptions {
httpProxyUrl?: string;
}

type ToolRunOptions = BaseToolRunOptions;

export interface OpenAPIEvents {
beforeFetch: Callback<{ url: URL }>;
afterFetch: Callback<{ data: OpenAPIToolOutput }>;
Expand All @@ -57,7 +59,7 @@ export class OpenAPIToolOutput extends StringToolOutput {
}
}

export class OpenAPITool extends Tool<OpenAPIToolOutput, OpenAPIToolOptions> {
export class OpenAPITool extends Tool<OpenAPIToolOutput, OpenAPIToolOptions, ToolRunOptions> {
name = "OpenAPI";
description = `OpenAPI tool that performs REST API requests to the servers and retrieves the response. The server API interfaces are defined in OpenAPI schema.
Only use the OpenAPI tool if you need to communicate to external servers.`;
Expand Down

0 comments on commit cf44945

Please sign in to comment.