camel-ai 0.2.76a0__py3-none-any.whl → 0.2.76a2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of camel-ai might be problematic. Click here for more details.
- camel/__init__.py +1 -1
- camel/agents/chat_agent.py +8 -1
- camel/environments/tic_tac_toe.py +1 -1
- camel/memories/__init__.py +2 -1
- camel/memories/agent_memories.py +3 -1
- camel/memories/blocks/chat_history_block.py +17 -2
- camel/models/base_model.py +30 -0
- camel/societies/workforce/single_agent_worker.py +44 -38
- camel/societies/workforce/workforce.py +10 -1
- camel/storages/object_storages/google_cloud.py +1 -1
- camel/toolkits/__init__.py +9 -2
- camel/toolkits/aci_toolkit.py +45 -0
- camel/toolkits/context_summarizer_toolkit.py +683 -0
- camel/toolkits/{file_write_toolkit.py → file_toolkit.py} +194 -34
- camel/toolkits/hybrid_browser_toolkit/config_loader.py +4 -0
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +67 -2
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +62 -45
- camel/toolkits/hybrid_browser_toolkit/ts/src/browser-session.ts +489 -60
- camel/toolkits/hybrid_browser_toolkit/ts/src/config-loader.ts +5 -2
- camel/toolkits/hybrid_browser_toolkit/ts/src/hybrid-browser-toolkit.ts +72 -12
- camel/toolkits/hybrid_browser_toolkit/ts/src/snapshot-parser.ts +2 -14
- camel/toolkits/hybrid_browser_toolkit/ts/src/types.ts +1 -0
- camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +228 -62
- camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +4 -4
- camel/toolkits/markitdown_toolkit.py +27 -1
- camel/toolkits/note_taking_toolkit.py +18 -8
- camel/toolkits/slack_toolkit.py +50 -1
- camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
- camel/toolkits/wechat_official_toolkit.py +483 -0
- camel/utils/context_utils.py +395 -0
- {camel_ai-0.2.76a0.dist-info → camel_ai-0.2.76a2.dist-info}/METADATA +84 -6
- {camel_ai-0.2.76a0.dist-info → camel_ai-0.2.76a2.dist-info}/RECORD +34 -30
- {camel_ai-0.2.76a0.dist-info → camel_ai-0.2.76a2.dist-info}/WHEEL +0 -0
- {camel_ai-0.2.76a0.dist-info → camel_ai-0.2.76a2.dist-info}/licenses/LICENSE +0 -0
|
@@ -73,6 +73,7 @@ export interface BrowserConfig {
|
|
|
73
73
|
// CDP connection options
|
|
74
74
|
connectOverCdp: boolean;
|
|
75
75
|
cdpUrl?: string;
|
|
76
|
+
cdpKeepCurrentPage: boolean;
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
export interface WebSocketConfig {
|
|
@@ -118,7 +119,7 @@ function getDefaultBrowserConfig(): BrowserConfig {
|
|
|
118
119
|
consoleLogLimit: 1000,
|
|
119
120
|
scrollPositionScale: 0.1,
|
|
120
121
|
navigationDelay: 100,
|
|
121
|
-
blankPageUrls: [],
|
|
122
|
+
blankPageUrls: ['chrome://newtab/', 'edge://newtab/', 'chrome://new-tab-page/'],
|
|
122
123
|
dataUrlPrefix: 'data:',
|
|
123
124
|
domContentLoadedState: 'domcontentloaded',
|
|
124
125
|
networkIdleState: 'networkidle',
|
|
@@ -139,7 +140,8 @@ function getDefaultBrowserConfig(): BrowserConfig {
|
|
|
139
140
|
height: 720
|
|
140
141
|
},
|
|
141
142
|
connectOverCdp: false,
|
|
142
|
-
cdpUrl: undefined
|
|
143
|
+
cdpUrl: undefined,
|
|
144
|
+
cdpKeepCurrentPage: false
|
|
143
145
|
};
|
|
144
146
|
}
|
|
145
147
|
|
|
@@ -218,6 +220,7 @@ export class ConfigLoader {
|
|
|
218
220
|
// CDP connection options
|
|
219
221
|
if (config.connectOverCdp !== undefined) browserConfig.connectOverCdp = config.connectOverCdp;
|
|
220
222
|
if (config.cdpUrl !== undefined) browserConfig.cdpUrl = config.cdpUrl;
|
|
223
|
+
if (config.cdpKeepCurrentPage !== undefined) browserConfig.cdpKeepCurrentPage = config.cdpKeepCurrentPage;
|
|
221
224
|
|
|
222
225
|
return new ConfigLoader(browserConfig, wsConfig);
|
|
223
226
|
}
|
|
@@ -15,7 +15,7 @@ export class HybridBrowserToolkit {
|
|
|
15
15
|
constructor(config: BrowserToolkitConfig = {}) {
|
|
16
16
|
this.configLoader = ConfigLoader.fromPythonConfig(config);
|
|
17
17
|
this.config = config; // Store original config for backward compatibility
|
|
18
|
-
this.session = new HybridBrowserSession(
|
|
18
|
+
this.session = new HybridBrowserSession(config); // Pass original config
|
|
19
19
|
this.viewportLimit = this.configLoader.getWebSocketConfig().viewport_limit;
|
|
20
20
|
this.fullVisualMode = this.configLoader.getWebSocketConfig().fullVisualMode || false;
|
|
21
21
|
}
|
|
@@ -26,9 +26,54 @@ export class HybridBrowserToolkit {
|
|
|
26
26
|
try {
|
|
27
27
|
await this.session.ensureBrowser();
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
const
|
|
29
|
+
// Check if we should skip navigation in CDP keep-current-page mode
|
|
30
|
+
const browserConfig = this.configLoader.getBrowserConfig();
|
|
31
|
+
if (browserConfig.cdpUrl && browserConfig.cdpKeepCurrentPage && !startUrl) {
|
|
32
|
+
// In CDP keep-current-page mode without explicit URL, just ensure browser and return current page
|
|
33
|
+
const snapshotStart = Date.now();
|
|
34
|
+
const snapshot = await this.getSnapshotForAction(this.viewportLimit);
|
|
35
|
+
const snapshotTime = Date.now() - snapshotStart;
|
|
36
|
+
|
|
37
|
+
const page = await this.session.getCurrentPage();
|
|
38
|
+
const currentUrl = page ? await page.url() : 'unknown';
|
|
39
|
+
|
|
40
|
+
const totalTime = Date.now() - startTime;
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
success: true,
|
|
44
|
+
message: `Browser opened in CDP keep-current-page mode (current page: ${currentUrl})`,
|
|
45
|
+
snapshot,
|
|
46
|
+
timing: {
|
|
47
|
+
total_time_ms: totalTime,
|
|
48
|
+
snapshot_time_ms: snapshotTime,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
31
52
|
|
|
53
|
+
// For normal mode or CDP with cdpKeepCurrentPage=false: navigate to URL
|
|
54
|
+
if (!browserConfig.cdpUrl || !browserConfig.cdpKeepCurrentPage) {
|
|
55
|
+
const url = startUrl || this.config.defaultStartUrl || 'https://google.com/';
|
|
56
|
+
const result = await this.session.visitPage(url);
|
|
57
|
+
|
|
58
|
+
const snapshotStart = Date.now();
|
|
59
|
+
const snapshot = await this.getSnapshotForAction(this.viewportLimit);
|
|
60
|
+
const snapshotTime = Date.now() - snapshotStart;
|
|
61
|
+
|
|
62
|
+
const totalTime = Date.now() - startTime;
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
success: true,
|
|
66
|
+
message: result.message,
|
|
67
|
+
snapshot,
|
|
68
|
+
timing: {
|
|
69
|
+
total_time_ms: totalTime,
|
|
70
|
+
page_load_time_ms: result.timing?.page_load_time_ms || 0,
|
|
71
|
+
snapshot_time_ms: snapshotTime,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Fallback: Just return current page snapshot without any navigation
|
|
32
77
|
const snapshotStart = Date.now();
|
|
33
78
|
const snapshot = await this.getSnapshotForAction(this.viewportLimit);
|
|
34
79
|
const snapshotTime = Date.now() - snapshotStart;
|
|
@@ -37,11 +82,10 @@ export class HybridBrowserToolkit {
|
|
|
37
82
|
|
|
38
83
|
return {
|
|
39
84
|
success: true,
|
|
40
|
-
message: `Browser opened
|
|
85
|
+
message: `Browser opened without navigation`,
|
|
41
86
|
snapshot,
|
|
42
87
|
timing: {
|
|
43
88
|
total_time_ms: totalTime,
|
|
44
|
-
...result.timing,
|
|
45
89
|
snapshot_time_ms: snapshotTime,
|
|
46
90
|
},
|
|
47
91
|
};
|
|
@@ -216,19 +260,27 @@ export class HybridBrowserToolkit {
|
|
|
216
260
|
private async executeActionWithSnapshot(action: BrowserAction): Promise<any> {
|
|
217
261
|
const result = await this.session.executeAction(action);
|
|
218
262
|
|
|
219
|
-
// Format response for Python layer compatibility
|
|
220
263
|
const response: any = {
|
|
221
264
|
result: result.message,
|
|
222
265
|
snapshot: '',
|
|
223
266
|
};
|
|
224
267
|
|
|
225
268
|
if (result.success) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
269
|
+
if (result.details?.diffSnapshot) {
|
|
270
|
+
response.snapshot = result.details.diffSnapshot;
|
|
271
|
+
|
|
272
|
+
if (result.timing) {
|
|
273
|
+
result.timing.snapshot_time_ms = 0; // Diff snapshot time is included in action time
|
|
274
|
+
}
|
|
275
|
+
} else {
|
|
276
|
+
// Get full snapshot as usual
|
|
277
|
+
const snapshotStart = Date.now();
|
|
278
|
+
response.snapshot = await this.getPageSnapshot(this.viewportLimit);
|
|
279
|
+
const snapshotTime = Date.now() - snapshotStart;
|
|
280
|
+
|
|
281
|
+
if (result.timing) {
|
|
282
|
+
result.timing.snapshot_time_ms = snapshotTime;
|
|
283
|
+
}
|
|
232
284
|
}
|
|
233
285
|
}
|
|
234
286
|
|
|
@@ -242,6 +294,14 @@ export class HybridBrowserToolkit {
|
|
|
242
294
|
response.newTabId = result.newTabId;
|
|
243
295
|
}
|
|
244
296
|
|
|
297
|
+
// Include details if present (excluding diffSnapshot as it's already in snapshot)
|
|
298
|
+
if (result.details) {
|
|
299
|
+
const { diffSnapshot, ...otherDetails } = result.details;
|
|
300
|
+
if (Object.keys(otherDetails).length > 0) {
|
|
301
|
+
response.details = otherDetails;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
245
305
|
return response;
|
|
246
306
|
}
|
|
247
307
|
|
|
@@ -21,26 +21,19 @@ export function parseSnapshotHierarchy(snapshotText: string): Map<string, Snapsh
|
|
|
21
21
|
for (const line of lines) {
|
|
22
22
|
if (!line.trim()) continue;
|
|
23
23
|
|
|
24
|
-
// Calculate indentation
|
|
25
24
|
const indent = line.length - line.trimStart().length;
|
|
26
25
|
|
|
27
|
-
// Extract
|
|
28
|
-
// Support both lines with : (have children) and without : (leaf nodes)
|
|
29
|
-
// Also support quoted lines like - 'button "text" [ref=...]'
|
|
30
|
-
// Also support escaped quotes in text
|
|
31
|
-
// Also support attributes before [ref=...]
|
|
32
|
-
// Extract type and optional label (before any [..] blocks)
|
|
26
|
+
// Extract type and optional label
|
|
33
27
|
const headerMatch = line.match(/^\s*(?:-\s*)?'?([a-z0-9_-]+)(?:\s+"((?:[^"\\]|\\.)*)")?/i);
|
|
34
28
|
if (!headerMatch) continue;
|
|
35
29
|
const [, typeRaw, label] = headerMatch;
|
|
36
30
|
const type = (typeRaw || 'unknown');
|
|
37
31
|
|
|
38
|
-
// Extract mandatory ref
|
|
39
32
|
const refMatch = line.match(/\[ref=([^\]]+)\]/i);
|
|
40
33
|
if (!refMatch) continue;
|
|
41
34
|
const ref = refMatch[1];
|
|
42
35
|
|
|
43
|
-
// Parse
|
|
36
|
+
// Parse bracketed attributes
|
|
44
37
|
const attrs: Record<string, string> = {};
|
|
45
38
|
for (const block of line.matchAll(/\[([^\]]+)\]/g)) {
|
|
46
39
|
const content = block[1];
|
|
@@ -53,12 +46,10 @@ export function parseSnapshotHierarchy(snapshotText: string): Map<string, Snapsh
|
|
|
53
46
|
}
|
|
54
47
|
}
|
|
55
48
|
|
|
56
|
-
// Update parent stack based on indentation
|
|
57
49
|
while (parentStack.length > 0 && parentStack[parentStack.length - 1].indent >= indent) {
|
|
58
50
|
parentStack.pop();
|
|
59
51
|
}
|
|
60
52
|
|
|
61
|
-
// Create node
|
|
62
53
|
const node: SnapshotNode = {
|
|
63
54
|
ref,
|
|
64
55
|
type: type.toLowerCase(),
|
|
@@ -68,15 +59,12 @@ export function parseSnapshotHierarchy(snapshotText: string): Map<string, Snapsh
|
|
|
68
59
|
parent: parentStack.length > 0 ? parentStack[parentStack.length - 1].ref : undefined
|
|
69
60
|
};
|
|
70
61
|
|
|
71
|
-
// Add to parent's children if has parent
|
|
72
62
|
if (node.parent && nodes.has(node.parent)) {
|
|
73
63
|
nodes.get(node.parent)!.children.push(ref);
|
|
74
64
|
}
|
|
75
65
|
|
|
76
|
-
// Add to nodes map
|
|
77
66
|
nodes.set(ref, node);
|
|
78
67
|
|
|
79
|
-
// Add to parent stack
|
|
80
68
|
parentStack.push({ ref, indent });
|
|
81
69
|
}
|
|
82
70
|
|
|
@@ -72,6 +72,7 @@ export interface BrowserToolkitConfig {
|
|
|
72
72
|
useNativePlaywrightMapping?: boolean; // New option to control mapping implementation
|
|
73
73
|
connectOverCdp?: boolean; // Whether to connect to existing browser via CDP
|
|
74
74
|
cdpUrl?: string; // WebSocket endpoint URL for CDP connection
|
|
75
|
+
cdpKeepCurrentPage?: boolean; // When true, CDP mode will keep the current page instead of creating new one
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
export interface ClickAction {
|