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.

Files changed (34) hide show
  1. camel/__init__.py +1 -1
  2. camel/agents/chat_agent.py +8 -1
  3. camel/environments/tic_tac_toe.py +1 -1
  4. camel/memories/__init__.py +2 -1
  5. camel/memories/agent_memories.py +3 -1
  6. camel/memories/blocks/chat_history_block.py +17 -2
  7. camel/models/base_model.py +30 -0
  8. camel/societies/workforce/single_agent_worker.py +44 -38
  9. camel/societies/workforce/workforce.py +10 -1
  10. camel/storages/object_storages/google_cloud.py +1 -1
  11. camel/toolkits/__init__.py +9 -2
  12. camel/toolkits/aci_toolkit.py +45 -0
  13. camel/toolkits/context_summarizer_toolkit.py +683 -0
  14. camel/toolkits/{file_write_toolkit.py → file_toolkit.py} +194 -34
  15. camel/toolkits/hybrid_browser_toolkit/config_loader.py +4 -0
  16. camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +67 -2
  17. camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +62 -45
  18. camel/toolkits/hybrid_browser_toolkit/ts/src/browser-session.ts +489 -60
  19. camel/toolkits/hybrid_browser_toolkit/ts/src/config-loader.ts +5 -2
  20. camel/toolkits/hybrid_browser_toolkit/ts/src/hybrid-browser-toolkit.ts +72 -12
  21. camel/toolkits/hybrid_browser_toolkit/ts/src/snapshot-parser.ts +2 -14
  22. camel/toolkits/hybrid_browser_toolkit/ts/src/types.ts +1 -0
  23. camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +228 -62
  24. camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +4 -4
  25. camel/toolkits/markitdown_toolkit.py +27 -1
  26. camel/toolkits/note_taking_toolkit.py +18 -8
  27. camel/toolkits/slack_toolkit.py +50 -1
  28. camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
  29. camel/toolkits/wechat_official_toolkit.py +483 -0
  30. camel/utils/context_utils.py +395 -0
  31. {camel_ai-0.2.76a0.dist-info → camel_ai-0.2.76a2.dist-info}/METADATA +84 -6
  32. {camel_ai-0.2.76a0.dist-info → camel_ai-0.2.76a2.dist-info}/RECORD +34 -30
  33. {camel_ai-0.2.76a0.dist-info → camel_ai-0.2.76a2.dist-info}/WHEEL +0 -0
  34. {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(this.configLoader.getBrowserConfig()); // Pass processed config
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
- const url = startUrl || this.config.defaultStartUrl || 'https://google.com/';
30
- const result = await this.session.visitPage(url);
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 and navigated to ${url}`,
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
- const snapshotStart = Date.now();
227
- response.snapshot = await this.getPageSnapshot(this.viewportLimit);
228
- const snapshotTime = Date.now() - snapshotStart;
229
-
230
- if (result.timing) {
231
- result.timing.snapshot_time_ms = snapshotTime;
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 element info using regex
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 all bracketed attributes except the [ref=...] block
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 {