Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into v1.51
Browse files Browse the repository at this point in the history
  • Loading branch information
wtfsayo committed Feb 2, 2025
2 parents 681d18a + 907def2 commit a897109
Show file tree
Hide file tree
Showing 34 changed files with 1,591 additions and 185 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,4 @@ lit-config.json

# Configuration to exclude the extra and local_docs directories
extra

**/dist/**
2 changes: 0 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ WORKDIR /app
# Copy built artifacts and production dependencies from the builder stage
COPY --from=builder /app/package.json ./
COPY --from=builder /app/pnpm-workspace.yaml ./
COPY --from=builder /app/eslint.config.mjs ./
COPY --from=builder /app/.eslintrc.json ./
COPY --from=builder /app/.npmrc ./
COPY --from=builder /app/turbo.json ./
COPY --from=builder /app/node_modules ./node_modules
Expand Down
22 changes: 12 additions & 10 deletions client/src/components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ChatInput } from "@/components/ui/chat/chat-input";
import { ChatMessageList } from "@/components/ui/chat/chat-message-list";
import { useTransition, animated, type AnimatedProps } from "@react-spring/web";
import { Paperclip, Send, X } from "lucide-react";
import { useEffect, useRef, useState, useCallback } from "react";
import { useEffect, useRef, useState } from "react";
import type { Content, UUID } from "@elizaos/core";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { apiClient } from "@/lib/api";
Expand All @@ -22,6 +22,7 @@ import AIWriter from "react-aiwriter";
import type { IAttachment } from "@/types";
import { AudioRecorder } from "./audio-recorder";
import { Badge } from "./ui/badge";
import { useAutoScroll } from "./ui/chat/hooks/useAutoScroll";

type ExtraContentFields = {
user: string;
Expand All @@ -39,7 +40,6 @@ export default function Page({ agentId }: { agentId: UUID }) {
const { toast } = useToast();
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const [input, setInput] = useState("");
const messagesContainerRef = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLTextAreaElement>(null);
const fileInputRef = useRef<HTMLInputElement>(null);
const formRef = useRef<HTMLFormElement>(null);
Expand All @@ -49,13 +49,10 @@ export default function Page({ agentId }: { agentId: UUID }) {
const getMessageVariant = (role: string) =>
role !== "user" ? "received" : "sent";

const scrollToBottom = useCallback(() => {
if (messagesContainerRef.current) {
messagesContainerRef.current.scrollTop =
messagesContainerRef.current.scrollHeight;
}
}, []);

const { scrollRef, isAtBottom, scrollToBottom, disableAutoScroll } = useAutoScroll({
smooth: true,
});

useEffect(() => {
scrollToBottom();
}, [queryClient.getQueryData(["messages", agentId])]);
Expand Down Expand Up @@ -176,7 +173,12 @@ export default function Page({ agentId }: { agentId: UUID }) {
return (
<div className="flex flex-col w-full h-[calc(100dvh)] p-4">
<div className="flex-1 overflow-y-auto">
<ChatMessageList ref={messagesContainerRef}>
<ChatMessageList
scrollRef={scrollRef}
isAtBottom={isAtBottom}
scrollToBottom={scrollToBottom}
disableAutoScroll={disableAutoScroll}
>
{transitions((style, message: ContentWithUser) => {
const variant = getMessageVariant(message?.user);
return (
Expand Down
13 changes: 5 additions & 8 deletions client/src/components/ui/chat/chat-message-list.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import * as React from "react";
import { ArrowDown } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useAutoScroll } from "@/components/ui/chat/hooks/useAutoScroll";

interface ChatMessageListProps extends React.HTMLAttributes<HTMLDivElement> {
scrollRef: React.RefObject<HTMLDivElement | null>;
isAtBottom: boolean;
scrollToBottom: () => void;
disableAutoScroll: () => void;
smooth?: boolean;
}

const ChatMessageList = React.forwardRef<HTMLDivElement, ChatMessageListProps>(
({ className, children, smooth = false, ...props }, _ref) => {
const { scrollRef, isAtBottom, scrollToBottom, disableAutoScroll } =
useAutoScroll({
smooth,
content: children,
});

({ className, children, scrollRef, isAtBottom, scrollToBottom, disableAutoScroll, ...props }) => {
return (
<div className="relative w-full h-full">
<div
Expand Down
2 changes: 2 additions & 0 deletions packages/client-twitter/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export async function buildConversationThread(
text: currentTweet.text,
source: "twitter",
url: currentTweet.permanentUrl,
imageUrls: currentTweet.photos.map((p) => p.url) || [],
inReplyTo: currentTweet.inReplyToStatusId
? stringToUuid(
currentTweet.inReplyToStatusId +
Expand Down Expand Up @@ -278,6 +279,7 @@ export async function sendTweet(
text: tweet.text,
source: "twitter",
url: tweet.permanentUrl,
imageUrls: tweet.photos.map((p) => p.url) || [],
inReplyTo: tweet.inReplyToStatusId
? stringToUuid(
tweet.inReplyToStatusId + "-" + client.runtime.agentId
Expand Down
7 changes: 7 additions & 0 deletions packages/core/__tests__/parsing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ describe("Parsing Module", () => {
});
});

it("should parse JSON objects containing array values", () => {
const input = '{"key": ["item1", "item2", "item3"]}';
expect(parseJSONObjectFromText(input)).toEqual({
key: ["item1", "item2", "item3"],
});
});

it("should handle empty objects", () => {
expect(parseJSONObjectFromText("```json\n{}\n```")).toEqual({});
expect(parseJSONObjectFromText("{}")).toEqual({});
Expand Down
6 changes: 3 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@
"@ai-sdk/google-vertex": "0.0.43",
"@ai-sdk/groq": "0.0.3",
"@ai-sdk/mistral": "1.0.9",
"@ai-sdk/openai": "1.0.5",
"@ai-sdk/openai": "1.1.9",
"@ai-sdk/amazon-bedrock": "1.1.0",
"@fal-ai/client": "1.2.0",
"@tavily/core": "^0.0.2",
"@types/uuid": "10.0.0",
"ai": "3.4.33",
"ai": "4.1.16",
"anthropic-vertex-ai": "1.0.2",
"dotenv": "16.4.5",
"fastembed": "1.14.1",
Expand All @@ -84,7 +84,7 @@
"js-tiktoken": "1.0.15",
"langchain": "0.3.6",
"ollama-ai-provider": "0.16.1",
"openai": "4.73.0",
"openai": "4.82.0",
"pino": "^9.6.0",
"pino-pretty": "^13.0.0",
"tinyld": "1.3.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/parsing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export const normalizeJsonString = (str: string) => {

// "key": unquotedValue → "key": "unquotedValue"
str = str.replace(
/("[\w\d_-]+")\s*: \s*(?!")([\s\S]+?)(?=(,\s*"|\}$))/g,
/("[\w\d_-]+")\s*: \s*(?!"|\[)([\s\S]+?)(?=(,\s*"|\}$))/g,
'$1: "$2"',
);

Expand Down
41 changes: 41 additions & 0 deletions packages/plugin-apro/biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"$schema": "https://biomejs.dev/schemas/1.5.3/schema.json",
"organizeImports": {
"enabled": false
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"noUnusedVariables": "error"
},
"suspicious": {
"noExplicitAny": "error"
},
"style": {
"useConst": "error",
"useImportType": "off"
}
}
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 4,
"lineWidth": 100
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"trailingCommas": "es5"
}
},
"files": {
"ignore": [
"dist/**/*",
"extra/**/*",
"node_modules/**/*"
]
}
}
12 changes: 10 additions & 2 deletions packages/plugin-apro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,22 @@
],
"dependencies": {
"@elizaos/core": "workspace:*",
"ai-agent-sdk-js": "^0.0.2"
"ai-agent-sdk-js": "^0.0.2",
"@ethersproject/contracts": "^5.7.0",
"@ethersproject/providers": "^5.7.0",
"ethers": "^5.7.2"
},
"scripts": {
"build": "tsup --format esm --dts",
"dev": "tsup --format esm --dts --watch",
"test": "vitest run"
"test": "vitest run",
"lint": "biome lint .",
"lint:fix": "biome check --apply .",
"format": "biome format .",
"format:fix": "biome format --write ."
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"tsup": "8.3.5",
"vitest": "2.1.4"
}
Expand Down
61 changes: 37 additions & 24 deletions packages/plugin-apro/src/actions/attpsPriceQuery.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Action, composeContext, elizaLogger, generateObject, HandlerCallback, IAgentRuntime, Memory, ModelClass, State } from "@elizaos/core";
import type { Action, HandlerCallback, IAgentRuntime, Memory, State } from "@elizaos/core";
import { composeContext, elizaLogger, generateObject, ModelClass } from "@elizaos/core";
import { attpsPriceQueryTemplate } from "../templates";
import { AttpsPriceQuery, AttpsPriceQueryResponse, AttpsPriceQuerySchema, isAttpsPriceQuery } from "../types";
import type { AttpsPriceQuery, AttpsPriceQueryResponse } from "../types";
import { AttpsPriceQuerySchema, isAttpsPriceQuery } from "../types";

async function fetchPriceData(sourceAgentId: string, feedId: string) {
const response = await fetch(`https://ai-agent-test.apro.com/api/ai-agent/price-detail?sourceAgentId=${sourceAgentId}&feedId=${feedId}`);
Expand All @@ -12,7 +14,7 @@ async function fetchPriceData(sourceAgentId: string, feedId: string) {
}

function cleanNumber(numStr: string) {
return parseFloat(numStr).toString();
return Number.parseFloat(numStr).toString();
}

export const attpsPriceQuery: Action = {
Expand All @@ -21,7 +23,7 @@ export const attpsPriceQuery: Action = {
'ATTPS_PRICE_FETCH',
],
description: "Call remote API to fetch price data for a given source agent id and feed id.",
validate: async (runtime: IAgentRuntime, message: Memory) => {
validate: async (_runtime: IAgentRuntime, _message: Memory) => {
return true;
},
handler: async (
Expand All @@ -31,10 +33,11 @@ export const attpsPriceQuery: Action = {
_options?: { [key: string]: unknown },
callback?: HandlerCallback
) => {
if (!state) {
state = (await runtime.composeState(message)) as State;
let currentState = state;
if (!currentState) {
currentState = (await runtime.composeState(message)) as State;
} else {
state = await runtime.updateRecentMessageState(state);
currentState = await runtime.updateRecentMessageState(currentState);
}

// Generate price query params
Expand All @@ -43,28 +46,33 @@ export const attpsPriceQuery: Action = {
const response = await generateObject({
runtime,
context: composeContext({
state,
state: currentState,
template: attpsPriceQueryTemplate,
}),
modelClass: ModelClass.LARGE,
schema: AttpsPriceQuerySchema,
});
attpsPriceQuery = response.object as AttpsPriceQuery;
elizaLogger.info('The price query params received:', attpsPriceQuery);
} catch (error: any) {
elizaLogger.error('Failed to generate price query params:', error);
callback({
text: 'Failed to generate price query params. Please provide valid input.',
});
} catch (error: unknown) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
elizaLogger.error('Failed to generate price query params:', errorMessage);
if (callback) {
callback({
text: 'Failed to generate price query params. Please provide valid input.',
});
}
return;
}

// Validate price query params
if (!isAttpsPriceQuery(attpsPriceQuery)) {
elizaLogger.error('Invalid price query params:', attpsPriceQuery);
callback({
text: 'Invalid price query params. Please provide valid input.',
});
if (callback) {
callback({
text: 'Invalid price query params. Please provide valid input.',
});
}
return;
}

Expand All @@ -75,14 +83,19 @@ export const attpsPriceQuery: Action = {
elizaLogger.info('The Price data received:', priceData);

const message = `Ask price: ${cleanNumber(priceData.askPrice)}\nBid price: ${cleanNumber(priceData.bidPrice)}\nMid price: ${cleanNumber(priceData.midPrice)}\nTimestamp: ${priceData.validTimeStamp}`;
callback({
text: `Here is the price data:\n${message}`,
});
} catch (error: any) {
elizaLogger.error(`Error fetching price data, error: `, error);
callback({
text: 'Error fetching price data, error: ' + error.message,
})
if (callback) {
callback({
text: `Here is the price data:\n${message}`,
});
}
} catch (error: unknown) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
elizaLogger.error('Error fetching price data:', errorMessage);
if (callback) {
callback({
text: `Error fetching price data: ${errorMessage}`,
});
}
}
},
examples: [
Expand Down
Loading

0 comments on commit a897109

Please sign in to comment.