Skip to content

Commit 3c635d3

Browse files
committed
Merge branch 'v2-develop' of https://github.com/elizaOS/eliza into v2-develop
2 parents a543dcf + 63ec80a commit 3c635d3

16 files changed

+108
-1057
lines changed

Dockerfile

+1-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ COPY packages ./packages
3030

3131
# Install dependencies
3232
RUN bun install
33-
RUN bun add better-sqlite3
3433

3534
# Build the project
3635
RUN bun run build
@@ -63,7 +62,7 @@ COPY --from=builder /app/scripts ./scripts
6362
ENV NODE_ENV=production
6463

6564
# Expose any necessary ports (if needed)
66-
EXPOSE 3000 5173
65+
EXPOSE 3000
6766

6867
# Start the application
6968
CMD ["bun", "run", "start"]

packages/cli/src/commands/create.ts

+94-7
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,99 @@ async function installDependencies(targetDir: string) {
7979
}
8080
}
8181

82+
/**
83+
* Stores Postgres URL in the global .env file
84+
* @param url The Postgres URL to store
85+
*/
86+
async function storePostgresUrl(url: string): Promise<void> {
87+
if (!url) return;
88+
89+
try {
90+
const homeDir = os.homedir();
91+
const globalEnvPath = path.join(homeDir, '.eliza', '.env');
92+
93+
await fs.writeFile(globalEnvPath, `POSTGRES_URL=${url}\n`, { flag: 'a' });
94+
logger.success('Postgres URL saved to configuration');
95+
} catch (error) {
96+
logger.warn('Error saving database configuration:', error);
97+
}
98+
}
99+
100+
/**
101+
* Validates a Postgres URL format
102+
* @param url The URL to validate
103+
* @returns True if the URL appears valid
104+
*/
105+
function isValidPostgresUrl(url: string): boolean {
106+
if (!url) return false;
107+
108+
// Basic pattern: postgresql://user:password@host:port/dbname
109+
const basicPattern = /^postgresql:\/\/[^:]+:[^@]+@[^:]+:\d+\/\w+$/;
110+
111+
// More permissive pattern (allows missing password, different formats)
112+
const permissivePattern = /^postgresql:\/\/.*@.*:\d+\/.*$/;
113+
114+
return basicPattern.test(url) || permissivePattern.test(url);
115+
}
116+
117+
/**
118+
* Prompts the user for a Postgres URL, validates it, and stores it
119+
* @returns The configured Postgres URL or null if user skips
120+
*/
121+
async function promptAndStorePostgresUrl(): Promise<string | null> {
122+
let isValidUrl = false;
123+
let userUrl = '';
124+
125+
while (!isValidUrl) {
126+
// Prompt for postgres url with simpler message
127+
const reply = await prompts({
128+
type: 'text',
129+
name: 'postgresUrl',
130+
message: 'Enter your Postgres URL:',
131+
validate: (value) => value.trim() !== '' || 'Postgres URL cannot be empty',
132+
});
133+
134+
// Handle cancellation
135+
if (!reply.postgresUrl) {
136+
const { continueAnyway } = await prompts({
137+
type: 'confirm',
138+
name: 'continueAnyway',
139+
message: 'Continue without configuring Postgres?',
140+
initial: false,
141+
});
142+
143+
if (continueAnyway) return null;
144+
continue;
145+
}
146+
147+
userUrl = reply.postgresUrl;
148+
149+
// Validate URL format
150+
if (!isValidPostgresUrl(userUrl)) {
151+
logger.warn("The URL format doesn't appear to be valid.");
152+
logger.info('Expected format: postgresql://user:password@host:port/dbname');
153+
154+
const { useAnyway } = await prompts({
155+
type: 'confirm',
156+
name: 'useAnyway',
157+
message: 'Use this URL anyway? (Choose Yes if you have a custom setup)',
158+
initial: false,
159+
});
160+
161+
if (!useAnyway) continue;
162+
}
163+
164+
isValidUrl = true;
165+
}
166+
167+
if (userUrl) {
168+
await storePostgresUrl(userUrl);
169+
return userUrl;
170+
}
171+
172+
return null;
173+
}
174+
82175
/**
83176
* Initialize a new project or plugin.
84177
*
@@ -288,13 +381,7 @@ export const create = new Command()
288381
}
289382

290383
if (database === 'postgres' && !postgresUrl) {
291-
// prompt for postgres url
292-
const reply = await prompts({
293-
type: 'text',
294-
name: 'postgresUrl',
295-
message: 'Enter your postgres url',
296-
});
297-
postgresUrl = reply.postgresUrl;
384+
postgresUrl = await promptAndStorePostgresUrl();
298385
}
299386

300387
// Set up src directory

packages/core/src/types.ts

-70
Original file line numberDiff line numberDiff line change
@@ -1167,21 +1167,6 @@ export interface IFileService extends Service {
11671167
generateSignedUrl(fileName: string, expiresIn: number): Promise<string>;
11681168
}
11691169

1170-
export interface ITeeLogService extends Service {
1171-
log(
1172-
agentId: string,
1173-
roomId: string,
1174-
entityId: string,
1175-
type: string,
1176-
content: string
1177-
): Promise<boolean>;
1178-
1179-
generateAttestation<T>(reportData: string, hashAlgorithm?: T | any): Promise<string>;
1180-
getAllAgents(): Promise<TeeAgent[]>;
1181-
getAgent(agentId: string): Promise<TeeAgent | null>;
1182-
getLogs(query: TeeLogQuery, page: number, pageSize: number): Promise<TeePageQuery<TeeLog[]>>;
1183-
}
1184-
11851170
export interface TestCase {
11861171
name: string;
11871172
fn: (runtime: IAgentRuntime) => Promise<void> | void;
@@ -1192,28 +1177,6 @@ export interface TestSuite {
11921177
tests: TestCase[];
11931178
}
11941179

1195-
// Represents a log entry in the TeeLog table, containing details about agent activities.
1196-
export interface TeeLog {
1197-
id: string;
1198-
agentId: string;
1199-
roomId: string;
1200-
entityId: string;
1201-
type: string;
1202-
content: string;
1203-
timestamp: number;
1204-
signature: string;
1205-
}
1206-
1207-
export interface TeeLogQuery {
1208-
agentId?: string;
1209-
roomId?: string;
1210-
entityId?: string;
1211-
type?: string;
1212-
containsContent?: string;
1213-
startTimestamp?: number;
1214-
endTimestamp?: number;
1215-
}
1216-
12171180
// Represents an agent in the TeeAgent table, containing details about the agent.
12181181
export interface TeeAgent {
12191182
id: string; // Primary key
@@ -1227,33 +1190,6 @@ export interface TeeAgent {
12271190
attestation: string;
12281191
}
12291192

1230-
export interface TeePageQuery<Result = any> {
1231-
page: number;
1232-
pageSize: number;
1233-
total?: number;
1234-
data?: Result;
1235-
}
1236-
1237-
export abstract class TeeLogDAO<DB = any> {
1238-
db: DB;
1239-
1240-
abstract initialize(): Promise<void>;
1241-
1242-
abstract addLog(log: TeeLog): Promise<boolean>;
1243-
1244-
abstract getPagedLogs(
1245-
query: TeeLogQuery,
1246-
page: number,
1247-
pageSize: number
1248-
): Promise<TeePageQuery<TeeLog[]>>;
1249-
1250-
abstract addAgent(agent: TeeAgent): Promise<boolean>;
1251-
1252-
abstract getAgent(agentId: string): Promise<TeeAgent>;
1253-
1254-
abstract getAllAgents(): Promise<TeeAgent[]>;
1255-
}
1256-
12571193
export enum TEEMode {
12581194
OFF = 'OFF',
12591195
LOCAL = 'LOCAL', // For local development with simulator
@@ -1282,13 +1218,7 @@ export interface RemoteAttestationMessage {
12821218
};
12831219
}
12841220

1285-
export interface SgxAttestation {
1286-
quote: string;
1287-
timestamp: number;
1288-
}
1289-
12901221
export enum TeeType {
1291-
SGX_GRAMINE = 'sgx_gramine',
12921222
TDX_DSTACK = 'tdx_dstack',
12931223
}
12941224

packages/plugin-tee/package.json

+3-4
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
"types": "dist/index.d.ts",
77
"dependencies": {
88
"@elizaos/core": "^1.0.0-alpha.67",
9-
"@phala/dstack-sdk": "^0.1.7",
10-
"@solana/web3.js": "^1.98.0",
11-
"better-sqlite3": "11.8.1",
12-
"elliptic": "6.6.1"
9+
"@phala/dstack-sdk": "0.1.11",
10+
"@solana/web3.js": "1.98.0",
11+
"viem": "2.23.11"
1312
},
1413
"devDependencies": {
1514
"@types/node": "^20.0.0",

packages/plugin-tee/src/actions/remoteAttestationAction.ts

-62
Original file line numberDiff line numberDiff line change
@@ -128,65 +128,3 @@ https://proof.t16z.com/reports/${data.checksum}`,
128128
],
129129
],
130130
};
131-
132-
/**
133-
* Marlin Remote Attestation action.
134-
*
135-
* This action allows generating a remote attestation to prove that the agent is running in a Trusted Execution Environment (TEE).
136-
*
137-
* @type {{
138-
* name: string,
139-
* similes: string[],
140-
* description: string,
141-
* handler: (runtime: IAgentRuntime, _message: Memory, _state: State, _options: Record<string, unknown>, callback: HandlerCallback) => Promise<boolean>,
142-
* validate: (runtime: IAgentRuntime) => Promise<boolean>,
143-
* examples: { name: string, content: { text: string, actions: string[] } }[][]
144-
* }}
145-
*/
146-
export const marlinRemoteAttestationAction = {
147-
name: 'REMOTE_ATTESTATION',
148-
similes: ['REMOTE_ATTESTATION', 'TEE_REMOTE_ATTESTATION', 'TEE_ATTESTATION'],
149-
description: 'Generate a remote attestation to prove that the agent is running in a TEE',
150-
handler: async (
151-
runtime: IAgentRuntime,
152-
_message: Memory,
153-
_state: State,
154-
_options: Record<string, unknown>, // Replaced any with Record<string, unknown>
155-
callback: HandlerCallback
156-
) => {
157-
try {
158-
const endpoint =
159-
runtime.getSetting('TEE_MARLIN_ATTESTATION_ENDPOINT') ?? 'http://127.0.0.1:1350';
160-
const response = await fetch(`${endpoint}/attestation/hex`);
161-
callback({
162-
text: `Here you go - ${await response.text()}`,
163-
actions: ['NONE'],
164-
});
165-
return true;
166-
} catch (error) {
167-
console.error('Failed to fetch remote attestation: ', error);
168-
return false;
169-
}
170-
},
171-
validate: async (_runtime: IAgentRuntime) => {
172-
return true;
173-
},
174-
examples: [
175-
[
176-
{
177-
name: 'user',
178-
content: {
179-
text: 'Attest yourself',
180-
actions: ['REMOTE_ATTESTATION'],
181-
},
182-
},
183-
{
184-
name: 'user',
185-
content: {
186-
text: 'Generate a remote attestation',
187-
actions: ['REMOTE_ATTESTATION'],
188-
},
189-
},
190-
],
191-
],
192-
};

0 commit comments

Comments
 (0)