Skip to content

Commit

Permalink
refactor: tools in seprate files
Browse files Browse the repository at this point in the history
  • Loading branch information
siddhart1o1 committed Jan 22, 2025
1 parent 6b3bab6 commit f7cf15b
Show file tree
Hide file tree
Showing 5 changed files with 587 additions and 137 deletions.
147 changes: 10 additions & 137 deletions apps/lana-chat/app/api/chat/route.ts
Original file line number Diff line number Diff line change
@@ -1,76 +1,18 @@
import { openai } from "@ai-sdk/openai";
import { streamText, tool } from "ai";
import { z } from "zod";
import {
getCustomerCreditFacility,
getCustomerDetails,
} from "./get-customer-details";

import {
CreditFacilitiesFilterBy,
CreditFacilitiesSortBy,
CollateralizationState,
CreditFacilityStatus,
SortDirection,
} from "@/lib/graphql/generated";
import {
getCreditFacilities,
getCreditFacilityById,
} from "./get-facility-details";
import { streamText } from "ai";
import { getCustomerDetailsTool } from "./tools/get-customer-details";
import { getCustomerCreditFacilitiesTool } from "./tools/get-customer-credit-facility";
import { getCreditFacilitiesTool } from "./tools/get-credit-facilities";
import { getCreditFacilityDetailsTool } from "./tools/get-credit-facility-details";

const systemPrompt = `
You are an assistant exclusively designed to help users explore and understand data from a banking and Bitcoin-focused application.
You must:
1. Focus solely on the banking and functions/tools response and there data, including accounts, credit facilities, transactions, approvals, and Bitcoin.
2. Use tables to present lists and structured data clearly, when applicable.
4. Highlight Bitcoin amounts in satoshis and USD when relevant.
5. Support users in queries, pagination, filtering, and sorting based on the schema.
3. Support users in queries, pagination, filtering, and sorting based on the schema.
You must not answer questions or provide assistance unrelated to this schema or the app.`;

const CollateralizationStateSchema = z
.nativeEnum(CollateralizationState)
.describe(`Collateralization states`);

const CreditFacilityStatusSchema = z
.nativeEnum(CreditFacilityStatus)
.describe(`Facility statuses`);

const CreditFacilitiesFilterBySchema = z
.nativeEnum(CreditFacilitiesFilterBy)
.describe(`Filter by fields`);

const CreditFacilitiesSortBySchema = z
.nativeEnum(CreditFacilitiesSortBy)
.describe(`Sort by fields`);

const SortDirectionSchema = z
.nativeEnum(SortDirection)
.describe(`Sort directions`);

const CreditFacilitiesFilterSchema = z
.object({
collateralizationState: CollateralizationStateSchema.optional().describe(
"Filter facilities by collateralization state"
),
field: CreditFacilitiesFilterBySchema.describe(
"Required field to filter facilities by"
),
status: CreditFacilityStatusSchema.optional().describe(
"Filter facilities by status"
),
})
.nullish()
.describe("Optional filters for credit facilities query");

const CreditFacilitiesSortSchema = z.object({
by: CreditFacilitiesSortBySchema.optional().describe(
"Field to sort facilities by"
),
direction: SortDirectionSchema.optional().describe(
"Sort direction (ascending/descending)"
),
});

export async function POST(req: Request) {
const { messages } = await req.json();

Expand All @@ -80,79 +22,10 @@ export async function POST(req: Request) {
messages,
maxSteps: 5,
tools: {
getCustomerDetails: tool({
type: "function",
description:
"Retrieve general information about a customer by their email address. This includes account balances, deposit history, withdrawal history, KYC document statuses, and basic customer information. **Note**: This does not include any details about the customer's credit facility.",
parameters: z.object({
email: z
.string()
.describe(
"The email address of the customer whose general details (excluding credit facility) are being requested."
),
}),
execute: async ({ email }) => {
return getCustomerDetails({ email });
},
}),
getCustomerCreditFacilities: tool({
type: "function",
description:
"Retrieve details about the customer's credit facility, including the facility amount, transactions, balance information, collateral, and associated terms. Use this tool to get credit-specific information about the customer.",
parameters: z.object({
email: z
.string()
.describe(
"The email address of the customer whose credit facility details are being requested."
),
}),
execute: async ({ email }) => {
return getCustomerCreditFacility({ email });
},
}),
getCreditFacilities: tool({
type: "function",
description:
"Retrieve list of credit facilities with filtering and sorting. When using filter with status or collateralizationState, you must also specify field as 'STATUS' or 'COLLATERALIZATION_STATE' respectively. Limited to 5 facilities per request.",
parameters: z.object({
first: z
.number()
.min(1)
.max(5)
.describe("Number of facilities to fetch (5 max: cannot exceed 5)"),
after: z
.string()
.optional()
.describe("Pagination cursor. Null/undefined for first page"),
sort: CreditFacilitiesSortSchema.optional(),
filter: CreditFacilitiesFilterSchema.optional(),
}),
execute: async ({ first, after, sort, filter }) => {
console.log({ first, after, sort, filter });
return getCreditFacilities({
first,
after,
sort,
filter,
});
},
}),
getCreditFacilityDetails: tool({
type: "function",
description: `Retrieve comprehensive details for a single credit facility. USE ONLY: when complete facility details are asked.`,
parameters: z.object({
id: z
.string()
.uuid()
.describe(
"UUID of the credit facility to fetch detailed information for"
),
}),
execute: async ({ id }) => {
console.log(id);
return getCreditFacilityById({ id });
},
}),
getCustomerDetails: getCustomerDetailsTool,
getCustomerCreditFacilities: getCustomerCreditFacilitiesTool,
getCreditFacilities: getCreditFacilitiesTool,
getCreditFacilityDetails: getCreditFacilityDetailsTool,
},
});

Expand Down
159 changes: 159 additions & 0 deletions apps/lana-chat/app/api/chat/tools/get-credit-facilities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { z } from "zod";
import { tool } from "ai";
import { gql } from "@apollo/client";
import { getClient } from "../client";
import {
CreditFacilitiesDocument,
CreditFacilitiesQuery,
CreditFacilitiesQueryVariables,
CreditFacilitiesFilterBy,
CreditFacilitiesSortBy,
CollateralizationState,
CreditFacilityStatus,
SortDirection,
} from "@/lib/graphql/generated";

const CollateralizationStateSchema = z
.nativeEnum(CollateralizationState)
.describe(`Collateralization states`);

const CreditFacilityStatusSchema = z
.nativeEnum(CreditFacilityStatus)
.describe(`Facility statuses`);

const CreditFacilitiesFilterBySchema = z
.nativeEnum(CreditFacilitiesFilterBy)
.describe(`Filter by fields`);

const CreditFacilitiesSortBySchema = z
.nativeEnum(CreditFacilitiesSortBy)
.describe(`Sort by fields`);

const SortDirectionSchema = z
.nativeEnum(SortDirection)
.describe(`Sort directions`);

const CreditFacilitiesFilterSchema = z
.object({
collateralizationState: CollateralizationStateSchema.optional().describe(
"Filter facilities by collateralization state"
),
field: CreditFacilitiesFilterBySchema.describe(
"Required field to filter facilities by"
),
status: CreditFacilityStatusSchema.optional().describe(
"Filter facilities by status"
),
})
.nullish()
.describe("Optional filters for credit facilities query");

const CreditFacilitiesSortSchema = z.object({
by: CreditFacilitiesSortBySchema.optional().describe(
"Field to sort facilities by"
),
direction: SortDirectionSchema.optional().describe(
"Sort direction (ascending/descending)"
),
});

gql`
query CreditFacilities(
$first: Int!
$after: String
$sort: CreditFacilitiesSort
$filter: CreditFacilitiesFilter
) {
creditFacilities(
first: $first
after: $after
sort: $sort
filter: $filter
) {
edges {
cursor
node {
id
creditFacilityId
collateralizationState
createdAt
status
facilityAmount
collateral
currentCvl {
disbursed
total
}
balance {
collateral {
btcBalance
}
outstanding {
usdBalance
}
}
customer {
customerId
email
}
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
`;

export const getCreditFacilities = async (
variables: CreditFacilitiesQueryVariables
) => {
try {
const response = await getClient().query<
CreditFacilitiesQuery,
CreditFacilitiesQueryVariables
>({
query: CreditFacilitiesDocument,
variables,
});

if (!response.data) {
return { error: "Data not found" };
}

return response;
} catch (error) {
if (error instanceof Error) {
return { error: error.message };
}
return { error: "An unknown error occurred" };
}
};

export const getCreditFacilitiesTool = tool({
type: "function",
description:
"Retrieve list of credit facilities with filtering and sorting. When using filter with status or collateralizationState, you must also specify field as 'STATUS' or 'COLLATERALIZATION_STATE' respectively. Limited to 5 facilities per request.",
parameters: z.object({
first: z
.number()
.min(1)
.max(5)
.describe("Number of facilities to fetch (5 max: cannot exceed 5)"),
after: z
.string()
.optional()
.describe("Pagination cursor. Null/undefined for first page"),
sort: CreditFacilitiesSortSchema.optional(),
filter: CreditFacilitiesFilterSchema.optional(),
}),
execute: async ({ first, after, sort, filter }) => {
return getCreditFacilities({
first,
after,
sort,
filter,
});
},
});
Loading

0 comments on commit f7cf15b

Please sign in to comment.