Skip to content

Commit fa86d8d

Browse files
committed
chore: resolve merge conflicts with develop
2 parents 07b8029 + 5f1ab1c commit fa86d8d

File tree

7 files changed

+313
-77
lines changed

7 files changed

+313
-77
lines changed

.env.example

+22-25
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ SUPABASE_ANON_KEY=
1717
# Remote character url (optional)
1818
REMOTE_CHARACTER_URL=
1919

20-
2120
###############################
2221
#### Client Configurations ####
2322
###############################
@@ -242,12 +241,11 @@ LARGE_VOLENGINE_MODEL= # Default: doubao-pro-256k
242241
VOLENGINE_EMBEDDING_MODEL= # Default: doubao-embedding
243242

244243
# DeepSeek Configuration
245-
DEEPSEEK_API_KEY= #Your DeepSeek API key
246-
DEEPSEEK_API_URL= # Default: https://api.deepseek.com
247-
SMALL_DEEPSEEK_MODEL= # Default: deepseek-chat
248-
MEDIUM_DEEPSEEK_MODEL= # Default: deepseek-chat
249-
LARGE_DEEPSEEK_MODEL= # Default: deepseek-chat
250-
244+
DEEPSEEK_API_KEY= #Your DeepSeek API key
245+
DEEPSEEK_API_URL= # Default: https://api.deepseek.com
246+
SMALL_DEEPSEEK_MODEL= # Default: deepseek-chat
247+
MEDIUM_DEEPSEEK_MODEL= # Default: deepseek-chat
248+
LARGE_DEEPSEEK_MODEL= # Default: deepseek-chat
251249

252250
# fal.ai Configuration
253251
FAL_API_KEY=
@@ -361,7 +359,7 @@ ZEROG_FLOW_ADDRESS=
361359

362360
# Squid Router
363361
SQUID_SDK_URL=https://apiplus.squidrouter.com # Default: https://apiplus.squidrouter.com
364-
SQUID_INTEGRATOR_ID= # get integrator id through https://docs.squidrouter.com/
362+
SQUID_INTEGRATOR_ID= # get integrator id through https://docs.squidrouter.com/
365363
SQUID_EVM_ADDRESS=
366364
SQUID_EVM_PRIVATE_KEY=
367365
SQUID_API_THROTTLE_INTERVAL= # Default: 0; Used to throttle API calls to avoid rate limiting (in ms)
@@ -375,22 +373,21 @@ SQUID_API_THROTTLE_INTERVAL= # Default: 0; Used to throttle API calls to avoid r
375373
TEE_MODE=OFF # LOCAL | DOCKER | PRODUCTION
376374
WALLET_SECRET_SALT= # ONLY define if you want to use TEE Plugin, otherwise it will throw errors
377375

378-
379376
# TEE Verifiable Log Configuration
380-
VLOG= # true/false; if you want to use TEE Verifiable Log, set this to "true"
377+
VLOG= # true/false; if you want to use TEE Verifiable Log, set this to "true"
381378

382379
# Galadriel Configuration
383-
GALADRIEL_API_KEY=gal-* # Get from https://dashboard.galadriel.com/
380+
GALADRIEL_API_KEY=gal-* # Get from https://dashboard.galadriel.com/
384381

385382
# Venice Configuration
386-
VENICE_API_KEY= # generate from venice settings
387-
SMALL_VENICE_MODEL= # Default: llama-3.3-70b
388-
MEDIUM_VENICE_MODEL= # Default: llama-3.3-70b
389-
LARGE_VENICE_MODEL= # Default: llama-3.1-405b
390-
IMAGE_VENICE_MODEL= # Default: fluently-xl
383+
VENICE_API_KEY= # generate from venice settings
384+
SMALL_VENICE_MODEL= # Default: llama-3.3-70b
385+
MEDIUM_VENICE_MODEL= # Default: llama-3.3-70b
386+
LARGE_VENICE_MODEL= # Default: llama-3.1-405b
387+
IMAGE_VENICE_MODEL= # Default: fluently-xl
391388

392389
# Akash Chat API Configuration docs: https://chatapi.akash.network/documentation
393-
AKASH_CHAT_API_KEY= # Get from https://chatapi.akash.network/
390+
AKASH_CHAT_API_KEY= # Get from https://chatapi.akash.network/
394391
SMALL_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-2-3B-Instruct
395392
MEDIUM_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-3-70B-Instruct
396393
LARGE_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-1-405B-Instruct-FP8
@@ -403,12 +400,12 @@ FAL_AI_LORA_PATH=
403400
TAVILY_API_KEY=
404401

405402
# WhatsApp Cloud API Configuration
406-
WHATSAPP_ACCESS_TOKEN= # Permanent access token from Facebook Developer Console
407-
WHATSAPP_PHONE_NUMBER_ID= # Phone number ID from WhatsApp Business API
408-
WHATSAPP_BUSINESS_ACCOUNT_ID= # Business Account ID from Facebook Business Manager
409-
WHATSAPP_WEBHOOK_VERIFY_TOKEN= # Custom string for webhook verification
410-
WHATSAPP_API_VERSION=v17.0 # WhatsApp API version (default: v17.0)
411-
ENABLE_TEE_LOG=false # Set to true to enable TEE logging, only available when running eliza in TEE
403+
WHATSAPP_ACCESS_TOKEN= # Permanent access token from Facebook Developer Console
404+
WHATSAPP_PHONE_NUMBER_ID= # Phone number ID from WhatsApp Business API
405+
WHATSAPP_BUSINESS_ACCOUNT_ID= # Business Account ID from Facebook Business Manager
406+
WHATSAPP_WEBHOOK_VERIFY_TOKEN= # Custom string for webhook verification
407+
WHATSAPP_API_VERSION=v17.0 # WhatsApp API version (default: v17.0)
408+
ENABLE_TEE_LOG=false # Set to true to enable TEE logging, only available when running eliza in TEE
412409

413410
# Flow Blockchain Configuration
414411
FLOW_ADDRESS=
@@ -505,11 +502,11 @@ INTIFACE_WEBSOCKET_URL=ws://localhost:12345
505502
GIPHY_API_KEY=
506503

507504
# OpenWeather
508-
OPEN_WEATHER_API_KEY= # OpenWeather API key
505+
OPEN_WEATHER_API_KEY= # OpenWeather API key
509506

510507
#GITCOIN Passport
511508
PASSPORT_API_KEY= #Gitcoin Passport key
512-
PASSPORT_SCORER= #Scorer number
509+
PASSPORT_SCORER= #Scorer number
513510

514511
# EchoChambers Configuration
515512
ECHOCHAMBERS_API_URL=http://127.0.0.1:3333

agent/src/index.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { SqliteDatabaseAdapter } from "@elizaos/adapter-sqlite";
55
import { SupabaseDatabaseAdapter } from "@elizaos/adapter-supabase";
66
import { AutoClientInterface } from "@elizaos/client-auto";
77
import { DiscordClientInterface } from "@elizaos/client-discord";
8-
import { FarcasterAgentClient } from "@elizaos/client-farcaster";
98
import { InstagramClientInterface } from "@elizaos/client-instagram";
109
import { LensAgentClient } from "@elizaos/client-lens";
1110
import { SlackClientInterface } from "@elizaos/client-slack";
@@ -30,10 +29,10 @@ import {
3029
IDatabaseAdapter,
3130
IDatabaseCacheAdapter,
3231
ModelProviderName,
32+
parseBooleanFromText,
3333
settings,
3434
stringToUuid,
3535
validateCharacterConfig,
36-
parseBooleanFromText,
3736
} from "@elizaos/core";
3837
import { zgPlugin } from "@elizaos/plugin-0g";
3938

@@ -618,10 +617,8 @@ export async function initializeClients(
618617
}
619618

620619
if (clientTypes.includes(Clients.FARCASTER)) {
621-
// why is this one different :(
622-
const farcasterClient = new FarcasterAgentClient(runtime);
620+
const farcasterClient = await FarcasterClientInterface.start(runtime);
623621
if (farcasterClient) {
624-
farcasterClient.start();
625622
clients.farcaster = farcasterClient;
626623
}
627624
}

packages/client-farcaster/src/client.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { IAgentRuntime, elizaLogger } from "@elizaos/core";
22
import { NeynarAPIClient, isApiErrorResponse } from "@neynar/nodejs-sdk";
33
import { NeynarCastResponse, Cast, Profile, FidRequest, CastId } from "./types";
4+
import { FarcasterConfig } from "./environment";
45

56
export class FarcasterClient {
67
runtime: IAgentRuntime;
78
neynar: NeynarAPIClient;
89
signerUuid: string;
910
cache: Map<string, any>;
1011
lastInteractionTimestamp: Date;
12+
farcasterConfig: FarcasterConfig;
1113

1214
constructor(opts: {
1315
runtime: IAgentRuntime;
@@ -16,12 +18,14 @@ export class FarcasterClient {
1618
neynar: NeynarAPIClient;
1719
signerUuid: string;
1820
cache: Map<string, any>;
21+
farcasterConfig: FarcasterConfig;
1922
}) {
2023
this.cache = opts.cache;
2124
this.runtime = opts.runtime;
2225
this.neynar = opts.neynar;
2326
this.signerUuid = opts.signerUuid;
2427
this.lastInteractionTimestamp = new Date();
28+
this.farcasterConfig = opts.farcasterConfig;
2529
}
2630

2731
async loadCastFromNeynarResponse(neynarResponse: any): Promise<Cast> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import {
2+
parseBooleanFromText,
3+
IAgentRuntime,
4+
ActionTimelineType,
5+
} from "@elizaos/core";
6+
import { z, ZodError } from "zod";
7+
8+
export const DEFAULT_MAX_CAST_LENGTH = 320;
9+
const DEFAULT_POLL_INTERVAL= 120; // 2 minutes
10+
const DEFAULT_POST_INTERVAL_MIN = 90; // 1.5 hours
11+
const DEFAULT_POST_INTERVAL_MAX = 180; // 3 hours
12+
/**
13+
* This schema defines all required/optional environment settings for Farcaster client
14+
*/
15+
export const farcasterEnvSchema = z.object({
16+
FARCASTER_DRY_RUN: z.boolean(),
17+
FARCASTER_FID: z.number().int().min(1, "Farcaster fid is required"),
18+
MAX_CAST_LENGTH: z.number().int().default(DEFAULT_MAX_CAST_LENGTH),
19+
FARCASTER_POLL_INTERVAL: z.number().int().default(DEFAULT_POLL_INTERVAL),
20+
ENABLE_POST: z.boolean(),
21+
POST_INTERVAL_MIN: z.number().int(),
22+
POST_INTERVAL_MAX: z.number().int(),
23+
ENABLE_ACTION_PROCESSING: z.boolean(),
24+
ACTION_INTERVAL: z.number().int(),
25+
POST_IMMEDIATELY: z.boolean(),
26+
MAX_ACTIONS_PROCESSING: z.number().int(),
27+
ACTION_TIMELINE_TYPE: z
28+
.nativeEnum(ActionTimelineType)
29+
.default(ActionTimelineType.ForYou),
30+
});
31+
32+
export type FarcasterConfig = z.infer<typeof farcasterEnvSchema>;
33+
34+
function safeParseInt(
35+
value: string | undefined | null,
36+
defaultValue: number
37+
): number {
38+
if (!value) return defaultValue;
39+
const parsed = parseInt(value, 10);
40+
return Number.isNaN(parsed) ? defaultValue : Math.max(1, parsed);
41+
}
42+
43+
/**
44+
* Validates or constructs a FarcasterConfig object using zod,
45+
* taking values from the IAgentRuntime or process.env as needed.
46+
*/
47+
export async function validateFarcasterConfig(
48+
runtime: IAgentRuntime
49+
): Promise<FarcasterConfig> {
50+
try {
51+
const farcasterConfig = {
52+
FARCASTER_DRY_RUN:
53+
parseBooleanFromText(
54+
runtime.getSetting("FARCASTER_DRY_RUN") ||
55+
process.env.FARCASTER_DRY_RUN ||
56+
"false"
57+
),
58+
59+
FARCASTER_FID: safeParseInt(
60+
runtime.getSetting("FARCASTER_FID") ||
61+
process.env.FARCASTER_FID,
62+
0
63+
),
64+
65+
MAX_CAST_LENGTH: safeParseInt(
66+
runtime.getSetting("MAX_CAST_LENGTH") ||
67+
process.env.MAX_CAST_LENGTH,
68+
DEFAULT_MAX_CAST_LENGTH
69+
),
70+
71+
FARCASTER_POLL_INTERVAL: safeParseInt(
72+
runtime.getSetting("FARCASTER_POLL_INTERVAL") ||
73+
process.env.FARCASTER_POLL_INTERVAL,
74+
DEFAULT_POLL_INTERVAL
75+
),
76+
77+
ENABLE_POST: parseBooleanFromText(
78+
runtime.getSetting("ENABLE_POST") ||
79+
process.env.ENABLE_POST ||
80+
"true"
81+
),
82+
83+
POST_INTERVAL_MIN: safeParseInt(
84+
runtime.getSetting("POST_INTERVAL_MIN") ||
85+
process.env.POST_INTERVAL_MIN,
86+
DEFAULT_POST_INTERVAL_MIN
87+
),
88+
89+
POST_INTERVAL_MAX: safeParseInt(
90+
runtime.getSetting("POST_INTERVAL_MAX") ||
91+
process.env.POST_INTERVAL_MAX,
92+
DEFAULT_POST_INTERVAL_MAX
93+
),
94+
95+
ENABLE_ACTION_PROCESSING:
96+
parseBooleanFromText(
97+
runtime.getSetting("ENABLE_ACTION_PROCESSING") ||
98+
process.env.ENABLE_ACTION_PROCESSING ||
99+
"false"
100+
) ?? false,
101+
102+
ACTION_INTERVAL: safeParseInt(
103+
runtime.getSetting("ACTION_INTERVAL") ||
104+
process.env.ACTION_INTERVAL,
105+
5 // 5 minutes
106+
),
107+
108+
POST_IMMEDIATELY:
109+
parseBooleanFromText(
110+
runtime.getSetting("POST_IMMEDIATELY") ||
111+
process.env.POST_IMMEDIATELY ||
112+
"false"
113+
) ?? false,
114+
115+
MAX_ACTIONS_PROCESSING: safeParseInt(
116+
runtime.getSetting("MAX_ACTIONS_PROCESSING") ||
117+
process.env.MAX_ACTIONS_PROCESSING,
118+
1
119+
),
120+
121+
ACTION_TIMELINE_TYPE: (
122+
runtime.getSetting("ACTION_TIMELINE_TYPE") ||
123+
process.env.ACTION_TIMELINE_TYPE ||
124+
ActionTimelineType.ForYou
125+
) as ActionTimelineType,
126+
};
127+
128+
return farcasterEnvSchema.parse(farcasterConfig);
129+
} catch (error) {
130+
if (error instanceof ZodError) {
131+
const errorMessages = error.errors
132+
.map((err) => `${err.path.join(".")}: ${err.message}`)
133+
.join("\n");
134+
throw new Error(
135+
`Farcaster configuration validation failed:\n${errorMessages}`
136+
);
137+
}
138+
throw error;
139+
}
140+
}

0 commit comments

Comments
 (0)