Skip to content

Commit

Permalink
Merge pull request #88 from auth0-lab/reorg_comps
Browse files Browse the repository at this point in the history
reorganize components code into folders
  • Loading branch information
cristiandouce authored Oct 15, 2024
2 parents 71caa35 + e24ea30 commit 2cf86d8
Show file tree
Hide file tree
Showing 29 changed files with 222 additions and 192 deletions.
133 changes: 67 additions & 66 deletions llm/actions/confirm-purchase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,24 @@ import { RELATION } from "@/lib/constants";
import { transactions } from "@/lib/db";
import { runAsyncFnWithoutBlocking } from "@/lib/utils";
import * as serialization from "@/llm/components/serialization";
import { StockPurchase } from "@/llm/components/stock-purchase";
import { StockPurchaseStatus } from "@/llm/components/stock-purchase-status";
import { StockPurchase } from "@/llm/components/stocks/stock-purchase";
import { StockPurchaseStatus } from "@/llm/components/stocks/stock-purchase-status";
import { ServerMessage } from "@/llm/types";
import { getUser, withFGA } from "@/sdk/fga";
import { withCheckPermission } from "@/sdk/fga/next/with-check-permission";

type confirmPurchaseParams = {
symbol: string,
price: number,
quantity: number,
symbol: string;
price: number;
quantity: number;

/**
* The message ID that triggered the component that called this action.
*/
messageID: string,
messageID: string;
};

const confirmPurchaseInternal = async (
{ symbol, price, quantity, messageID }: confirmPurchaseParams
) => {
const confirmPurchaseInternal = async ({ symbol, price, quantity, messageID }: confirmPurchaseParams) => {
"use server";
const user = await getUser();
const history = getMutableAIState();
Expand All @@ -38,74 +36,77 @@ const confirmPurchaseInternal = async (
await new Promise((resolve) => setTimeout(resolve, 1000));

purchasing.update(
<StockPurchaseStatus
message={`Purchasing ${quantity} ${symbol}... working on it...`}
status="in-progress" />
<StockPurchaseStatus message={`Purchasing ${quantity} ${symbol}... working on it...`} status="in-progress" />
);

await transactions.create(symbol, price, quantity, "buy", user.sub);
const message = `You have successfully purchased ${quantity} $${symbol}.`;
purchasing.done(
<StockPurchaseStatus
message={message}
status="success" />
);
purchasing.done(<StockPurchaseStatus message={message} status="success" />);

history.done((messages: ServerMessage[]) => messages.map(m => {
return m.id === messageID ? {
...m,
content: `User has successfully purchased ${quantity} stocks of ${symbol} at the price of $ ${price}.`,
componentName: serialization.names.get(StockPurchase),
params: {
...m.params,
result: {
message,
status: "success",
}
}
} : m;
}));
history.done((messages: ServerMessage[]) =>
messages.map((m) => {
return m.id === messageID
? {
...m,
content: `User has successfully purchased ${quantity} stocks of ${symbol} at the price of $ ${price}.`,
componentName: serialization.names.get(StockPurchase),
params: {
...m.params,
result: {
message,
status: "success",
},
},
}
: m;
})
);
});

return {
purchasingUI: purchasing.value,
};
}
};

export const confirmPurchase = withCheckPermission({
checker: async (params) => {
return withFGA({
object: `asset:${params.symbol.toLowerCase()}`,
relation: RELATION.CAN_BUY_STOCKS,
context: { current_time: new Date().toISOString() },
});
},
onUnauthorized: async (params) => {
const purchasing = createStreamableUI(null);
const history = getMutableAIState();
const message = `You are not authorized to purchase ${params.quantity} stocks of ${params.symbol}.`;
export const confirmPurchase = withCheckPermission(
{
checker: async (params) => {
return withFGA({
object: `asset:${params.symbol.toLowerCase()}`,
relation: RELATION.CAN_BUY_STOCKS,
context: { current_time: new Date().toISOString() },
});
},
onUnauthorized: async (params) => {
const purchasing = createStreamableUI(null);
const history = getMutableAIState();
const message = `You are not authorized to purchase ${params.quantity} stocks of ${params.symbol}.`;

purchasing.done(
<StockPurchaseStatus message={message} status="failure" />
);
purchasing.done(<StockPurchaseStatus message={message} status="failure" />);

history.done((messages: ServerMessage[]) => messages.map(m => {
return m.id === params.messageID ? {
...m,
content: message,
componentName: serialization.names.get(StockPurchase),
params: {
...m.params,
result: {
status: "failure",
message,
}
}
} : m;
}));
history.done((messages: ServerMessage[]) =>
messages.map((m) => {
return m.id === params.messageID
? {
...m,
content: message,
componentName: serialization.names.get(StockPurchase),
params: {
...m.params,
result: {
status: "failure",
message,
},
},
}
: m;
})
);

return {
purchasingUI: purchasing.value,
};
}
}, confirmPurchaseInternal);
return {
purchasingUI: purchasing.value,
};
},
},
confirmPurchaseInternal
);
19 changes: 8 additions & 11 deletions llm/actions/continue-conversation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import { userUsage } from "@/lib/db";
import { composeTools } from "@/llm/ai-helpers";
import * as serialization from "@/llm/components/serialization";
import { getSystemPrompt } from "@/llm/system-prompt";
import getEvents from "@/llm/tools/events/get-events";
import getForecasts from "@/llm/tools/forecasts/get-forecasts";
import checkSubscription from "@/llm/tools/newsletter/check-subscription";
import setSubscription from "@/llm/tools/newsletter/set-subscription";
import setEmployeer from "@/llm/tools/profile/set-employeer";
import setProfileAttributes from "@/llm/tools/profile/set-profile-attributes";
import getEvents from "@/llm/tools/schedule/get-events";
import addConditionalPurchase from "@/llm/tools/trading/add-conditional-purchase";
import getForecasts from "@/llm/tools/trading/get-forecasts";
import listStocks from "@/llm/tools/trading/list-stocks";
import showCurrentPositions from "@/llm/tools/trading/show-current-positions";
import showStockPrice from "@/llm/tools/trading/show-stock-price";
Expand All @@ -37,15 +37,13 @@ type ContinueConversationParams = {
hidden: boolean;
};

export async function continueConversation(
input: string | ContinueConversationParams
): Promise<ClientMessage> {
export async function continueConversation(input: string | ContinueConversationParams): Promise<ClientMessage> {
"use server";
const user = await getUser();
const history = getMutableAIState();

let hidden = false;
if (typeof input === 'object') {
if (typeof input === "object") {
hidden = input.hidden;
input = input.message;
}
Expand All @@ -58,10 +56,7 @@ export async function continueConversation(
};
}

history.update((messages: ServerMessage[]) => [
...messages,
{ role: "user", content: input, hidden },
]);
history.update((messages: ServerMessage[]) => [...messages, { role: "user", content: input, hidden }]);

const promptMessages = history.get();

Expand Down Expand Up @@ -101,7 +96,9 @@ export async function continueConversation(
// TODO: implement a max token limit
onFinish: async ({ usage }) => {
const stats = await userUsage.track(user.sub, usage);
console.log(`User ${user.email} used ${usage.totalTokens} tokens in this conversation. Last hour: ${stats.lastHour}, last day: ${stats.lastDay}.`);
console.log(
`User ${user.email} used ${usage.totalTokens} tokens in this conversation. Last hour: ${stats.lastHour}, last day: ${stats.lastDay}.`
);
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
import { EnsureAPIAccess } from "@/sdk/components/ensure-api-access";

import { Event, EventAvailability } from "../actions/calendar-events";
import { NotAvailableReadOnly } from "./not-available-read-only";
import { Event, EventAvailability } from "../../actions/calendar-events";
import { NotAvailableReadOnly } from "../not-available-read-only";

export function CalendarEvents({
events,
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

import { format, parseISO } from "date-fns";

import { checkAvailabilityForEvents } from "../actions/calendar-events";
import { checkAvailabilityForEvents } from "@/llm/actions/calendar-events";

import WarningWrapper from "../warning-wrapper";
import { CalendarEvents } from "./calendar-events";
import WarningWrapper from "./warning-wrapper";

interface Event {
date: string;
Expand Down
2 changes: 2 additions & 0 deletions llm/components/events/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { Events } from "./events";
export { EventsSkeleton } from "./events-skeleton";
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { useEffect, useState } from "react";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import { ClientMessage, Document } from "@/llm/types";

import { FormattedText } from "./FormattedText";
import { NotAvailableReadOnly } from "./not-available-read-only";
import { PromptUserContainer } from "./prompt-user-container";
import WarningWrapper from "./warning-wrapper";
import { FormattedText } from "../FormattedText";
import { NotAvailableReadOnly } from "../not-available-read-only";
import { PromptUserContainer } from "../prompt-user-container";
import WarningWrapper from "../warning-wrapper";

export const Documents = ({
documents,
Expand Down
1 change: 1 addition & 0 deletions llm/components/forecasts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Documents } from "./documents";
13 changes: 3 additions & 10 deletions llm/components/serialization.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { ConditionalPurchase } from "./conditional-purchase";
import { Documents } from "./documents";
import { Events } from "./events";
import { Documents } from "./forecasts/documents";
import { FormattedText } from "./FormattedText";
import { Positions } from "./positions";
import { SimpleMessage } from "./simple-message";
import { Stock } from "./stock";
import { StockPurchase } from "./stock-purchase";
import { Stocks } from "./stocks";
import { ConditionalPurchase, Positions, Stock, StockPurchase, Stocks } from "./stocks";

export const components = {
Documents,
Expand All @@ -24,8 +20,5 @@ type ComponentsNames = keyof typeof components;
type ComponentClasses = (typeof components)[ComponentsNames];

export const names = new Map<ComponentClasses, ComponentsNames>(
Object.entries(components).map(([name, component]) => [
component,
name as ComponentsNames,
])
Object.entries(components).map(([name, component]) => [component, name as ComponentsNames])
);
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { ConditionalPurchase as ConditionalPurchaseType } from "@/lib/db/conditi
import { getConditionalPurchaseById } from "@/llm/actions/conditional-purchases";
import { isGuardianEnrolled } from "@/sdk/auth0/mgmt";

import { NotAvailableReadOnly } from "./not-available-read-only";
import WarningWrapper from "./warning-wrapper";
import { NotAvailableReadOnly } from "../not-available-read-only";
import WarningWrapper from "../warning-wrapper";

export function ConditionalPurchase({
id,
Expand Down
8 changes: 8 additions & 0 deletions llm/components/stocks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export { Stocks } from "./stocks";
export { StocksSkeleton } from "./stocks-skeleton";
export { Stock } from "./stock";
export { StockSkeleton } from "./stock-skeleton";
export { StockPurchase } from "./stock-purchase";
export { StockPurchaseStatus } from "./stock-purchase-status";
export { ConditionalPurchase } from "./conditional-purchase";
export { Positions } from "./positions";
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { useActions, useUIState } from "ai/rsc";

import { transactions } from "@/lib/db";
import { cn } from "@/lib/utils";
import { ClientMessage } from "@/llm/types";

import { ClientMessage } from "../types";
import WarningWrapper from "./warning-wrapper";
import WarningWrapper from "../warning-wrapper";

export function Positions({ positions, readOnly = false }: { positions: transactions.Position[]; readOnly?: boolean }) {
const [, setMessages] = useUIState();
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { useId, useState } from "react";
import { StockDownIcon, StockUpIcon } from "@/components/icons";
import { formatNumber } from "@/lib/utils";

import WarningWrapper from "../warning-wrapper";
import { StockPurchaseStatus } from "./stock-purchase-status";
import WarningWrapper from "./warning-wrapper";

type StockPurchaseUIParams = {
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import WarningWrapper from "./warning-wrapper";
import WarningWrapper from "../warning-wrapper";

export const StockSkeleton = () => {
return (
Expand Down
3 changes: 1 addition & 2 deletions llm/components/stock.tsx → llm/components/stocks/stock.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable react-hooks/exhaustive-deps */
"use client";

import { scaleLinear } from "d3-scale";
Expand All @@ -8,7 +7,7 @@ import { useResizeObserver } from "usehooks-ts";

import { StockDownIcon, StockUpIcon } from "@/components/icons";

import WarningWrapper from "./warning-wrapper";
import WarningWrapper from "../warning-wrapper";

export function Stock({
symbol,
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { useActions, useUIState } from "ai/rsc";
import { StockDownIcon, StockUpIcon } from "@/components/icons";
import { cn } from "@/lib/utils";

import { ClientMessage } from "../types";
import WarningWrapper from "./warning-wrapper";
import { ClientMessage } from "../../types";
import WarningWrapper from "../warning-wrapper";

export function Stocks({ stocks, readOnly = false }: { stocks: any[]; readOnly?: boolean }) {
const [, setMessages] = useUIState();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import { z } from "zod";

import { getCompanyInfo } from "@/lib/market/stocks";
import { defineTool } from "@/llm/ai-helpers";
import { Events } from "@/llm/components/events";
import { EventsSkeleton } from "@/llm/components/events-skeleton";
import { Events, EventsSkeleton } from "@/llm/components/events";
import * as serialization from "@/llm/components/serialization";
import { getHistory } from "@/llm/utils";

/**
* This tool is used to get upcoming events for a stock.
* The events are automatically generated by the LLM.
*/
export default defineTool("get_events", () => {
const history = getHistory();

Expand Down
Loading

0 comments on commit 2cf86d8

Please sign in to comment.