Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
node_modules
npm-debug.log
npm-debug.log

.env
.env.*

configs/.env.*
23 changes: 13 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"start": "bun run server.ts --server-options=\"{\\\"idleTimeout\\\": 120000}\"",
"dev": "bun run --watch server.ts --server-options=\"{\\\"idleTimeout\\\": 120000}\"",
"test": "vitest run",
"test:watch": "vitest",
"coverage": "vitest --coverage",
"format": "bun prettier . --write"
},
Expand All @@ -17,30 +18,32 @@
"@ai-sdk/anthropic": "^1.1.9",
"@ai-sdk/deepseek": "^0.1.11",
"@ai-sdk/openai": "^1.1.13",
"@dimo-network/data-sdk": "^1.2.3",
"@dimo-network/data-sdk": "1.2.3",
"@langchain/community": "^0.3.32",
"@langchain/core": "^0.3.40",
"@langchain/openai": "^0.4.4",
"@langchain/qdrant": "^0.1.1",
"@qdrant/js-client-rest": "^1.13.0",
"@upstash/redis": "^1.34.4",
"ai": "^4.1.45",
"axios": "^1.7.9",
"chalk": "^4.1.2",
"dotenv": "^16.4.7",
"ethers": "^6.13.5",
"hono": "^4.6.16",
"langchain": "^0.3.19",
"logform": "^2.7.0",
"typescript": "^5.7.2",
"uuid": "^11.1.0",
"winston": "^3.17.0",
"zod": "^3.24.2",
"@qdrant/js-client-rest": "^1.13.0",
"@langchain/qdrant": "^0.1.1",
"@upstash/redis": "^1.34.4",
"@langchain/community": "^0.3.32",
"@langchain/core": "^0.3.40",
"@langchain/openai": "^0.4.4",
"langchain": "^0.3.19"
"zod": "^3.24.2"
},
"devDependencies": {
"@types/axios": "^0.14.4",
"@types/node": "^22.10.5",
"@vitest/coverage-v8": "2.1.8",
"prettier": "^3.4.2",
"vitest": "^2.1.8"
}
},
"packageManager": "pnpm@10.6.3+sha512.bb45e34d50a9a76e858a95837301bfb6bd6d35aea2c5d52094fa497a467c43f5c440103ce2511e9e0a2f89c3d6071baac3358fc68ac6fb75e2ceb3d2736065e6"
}
135 changes: 0 additions & 135 deletions src/tools/__tests__/dify.test.ts

This file was deleted.

109 changes: 109 additions & 0 deletions src/tools/__tests__/twnebula.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { describe, it, expect, beforeEach, vi } from "vitest";
import axios from "axios";
import { ZodError } from "zod";

import { ThirdWebTool } from "../thirdWeb";

vi.mock("axios");

const baseUrl = "https://nebula-api.thirdweb.com/chat";

describe("ThirdWebTool", () => {
let tool: ThirdWebTool;
const mockSecretKey = "test-secret-key";
const mockSessionId = "test-session-id";

beforeEach(() => {
process.env.THIRDWEB_SECRET_KEY = mockSecretKey;
process.env.THIRDWEB_SESSION_ID = mockSessionId;
tool = new ThirdWebTool();
});

it("should initialize with correct properties", () => {
expect(tool.name).toBe("ask_thirdweb");
expect(tool.description).toContain(
"Retrieve smart contract details"
);
expect(tool.schema).toHaveLength(1);
expect(tool.schema[0].name).toBe("ask_thirdweb");
});

it("should throw error when secret key is not set", () => {
delete process.env.THIRDWEB_SECRET_KEY;
process.env.THIRDWEB_SESSION_ID = mockSessionId;
expect(() => new ThirdWebTool()).toThrow(
"Please set the THIRDWEB_SECRET_KEY environment variable."
);
});

it("should throw error when session ID is not set", () => {
process.env.THIRDWEB_SECRET_KEY = mockSecretKey;
delete process.env.THIRDWEB_SESSION_ID;
expect(() => new ThirdWebTool()).toThrow(
"Please set the THIRDWEB_SESSION_ID environment variable."
);
});

describe("getRawData", () => {
const mockNebulaResponse = {
message: "This is a test response from Nebula",
actions: [
{
session_id: "test-session-id",
request_id: "test-request-id",
type: "init",
source: "nebula",
data: "Test data"
}
],
session_id: "test-session-id",
request_id: "test-request-id"
};

it("should handle successful API response", async () => {
vi.mocked(axios.post).mockResolvedValueOnce({ data: mockNebulaResponse });

const result = await tool.getRawData({ message: "Test question about blockchain" });

expect(result).toEqual(mockNebulaResponse);
expect(axios.post).toHaveBeenCalledWith(
baseUrl,
{
message: "Test question about blockchain",
stream: false,
session_id: mockSessionId
},
{
headers: {
"x-secret-key": mockSecretKey,
"Content-Type": "application/json"
},
timeout: 60000
}
);
});

it("should throw error for empty message", async () => {
await expect(tool.getRawData({ message: "" })).rejects.toEqual(
new ZodError([
{
code: "too_small",
minimum: 20,
type: "string",
inclusive: true,
exact: false,
message: "String must contain at least 20 character(s)",
path: ["message"],
},
])
);
});

it("should handle network errors", async () => {
const networkError = new Error("Network error");
vi.mocked(axios.post).mockRejectedValueOnce(networkError);

await expect(tool.getRawData({ message: "Test question about blockchain" })).rejects.toThrow("Network error");
});
});
});
Loading