narada 0.1.30__tar.gz → 0.1.32__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: narada
3
- Version: 0.1.30
3
+ Version: 0.1.32
4
4
  Summary: Python client SDK for Narada
5
5
  Project-URL: Homepage, https://github.com/NaradaAI/narada-python-sdk/narada
6
6
  Project-URL: Repository, https://github.com/NaradaAI/narada-python-sdk
@@ -9,7 +9,7 @@ Author-email: Narada <support@narada.ai>
9
9
  License-Expression: Apache-2.0
10
10
  Requires-Python: >=3.12
11
11
  Requires-Dist: aiohttp>=3.12.13
12
- Requires-Dist: narada-core==0.0.8
12
+ Requires-Dist: narada-core==0.0.10
13
13
  Requires-Dist: playwright>=1.53.0
14
14
  Requires-Dist: rich>=14.0.0
15
15
  Requires-Dist: semver>=3.0.4
@@ -1,13 +1,13 @@
1
1
  [project]
2
2
  name = "narada"
3
- version = "0.1.30"
3
+ version = "0.1.32"
4
4
  description = "Python client SDK for Narada"
5
5
  license = "Apache-2.0"
6
6
  readme = "README.md"
7
7
  authors = [{ name = "Narada", email = "support@narada.ai" }]
8
8
  requires-python = ">=3.12"
9
9
  dependencies = [
10
- "narada-core==0.0.8",
10
+ "narada-core==0.0.10",
11
11
  "aiohttp>=3.12.13",
12
12
  "playwright>=1.53.0",
13
13
  "rich>=14.0.0",
@@ -1,3 +1,8 @@
1
+ from narada.client import Narada
2
+ from narada.config import BrowserConfig, ProxyConfig
3
+ from narada.utils import download_file, render_html
4
+ from narada.version import __version__
5
+ from narada.window import LocalBrowserWindow, RemoteBrowserWindow
1
6
  from narada_core.errors import (
2
7
  NaradaError,
3
8
  NaradaExtensionMissingError,
@@ -8,12 +13,6 @@ from narada_core.errors import (
8
13
  )
9
14
  from narada_core.models import Agent, File, Response, ResponseContent
10
15
 
11
- from narada.client import Narada
12
- from narada.config import BrowserConfig, ProxyConfig
13
- from narada.utils import download_file, render_html
14
- from narada.version import __version__
15
- from narada.window import LocalBrowserWindow, RemoteBrowserWindow
16
-
17
16
  __all__ = [
18
17
  "__version__",
19
18
  "Agent",
@@ -11,6 +11,10 @@ from uuid import uuid4
11
11
 
12
12
  import aiohttp
13
13
  import semver
14
+ from narada.config import BrowserConfig, ProxyConfig
15
+ from narada.utils import assert_never
16
+ from narada.version import __version__
17
+ from narada.window import LocalBrowserWindow, create_side_panel_url
14
18
  from narada_core.errors import (
15
19
  NaradaExtensionMissingError,
16
20
  NaradaExtensionUnauthenticatedError,
@@ -26,19 +30,14 @@ from playwright.async_api import (
26
30
  ElementHandle,
27
31
  Page,
28
32
  Playwright,
29
- async_playwright,
30
33
  )
34
+ from playwright.async_api import TimeoutError as PlaywrightTimeoutError
31
35
  from playwright.async_api import (
32
- TimeoutError as PlaywrightTimeoutError,
36
+ async_playwright,
33
37
  )
34
38
  from playwright.async_api._context_manager import PlaywrightContextManager
35
39
  from rich.console import Console
36
40
 
37
- from narada.config import BrowserConfig, ProxyConfig
38
- from narada.utils import assert_never
39
- from narada.version import __version__
40
- from narada.window import LocalBrowserWindow, create_side_panel_url
41
-
42
41
 
43
42
  @dataclass
44
43
  class _LaunchBrowserResult:
@@ -4,28 +4,35 @@ import time
4
4
  from abc import ABC
5
5
  from http import HTTPStatus
6
6
  from pathlib import Path
7
- from typing import IO, Any, Optional, TypeVar, overload
7
+ from typing import IO, Any, TypeVar, overload
8
8
 
9
9
  import aiohttp
10
+ from narada.config import BrowserConfig
10
11
  from narada_core.actions.models import (
11
- ActionTraceItem,
12
+ AgenticMouseAction,
13
+ AgenticMouseActionRequest,
12
14
  AgenticSelectorAction,
13
15
  AgenticSelectorRequest,
14
16
  AgenticSelectorResponse,
15
- AgenticMouseActionRequest,
16
- AgenticMouseAction,
17
17
  AgenticSelectors,
18
18
  AgentResponse,
19
19
  AgentUsage,
20
20
  CloseWindowRequest,
21
21
  ExtensionActionRequest,
22
22
  ExtensionActionResponse,
23
+ GetFullHtmlRequest,
24
+ GetFullHtmlResponse,
25
+ GetScreenshotRequest,
26
+ GetScreenshotResponse,
27
+ GetSimplifiedHtmlRequest,
28
+ GetSimplifiedHtmlResponse,
23
29
  GoToUrlRequest,
24
30
  PrintMessageRequest,
25
31
  ReadGoogleSheetRequest,
26
32
  ReadGoogleSheetResponse,
27
- WriteGoogleSheetRequest,
28
33
  RecordedClick,
34
+ WriteGoogleSheetRequest,
35
+ parse_action_trace,
29
36
  )
30
37
  from narada_core.errors import (
31
38
  NaradaAgentTimeoutError_INTERNAL_DO_NOT_USE,
@@ -35,6 +42,7 @@ from narada_core.errors import (
35
42
  from narada_core.models import (
36
43
  Agent,
37
44
  File,
45
+ McpServer,
38
46
  RemoteDispatchChatHistoryItem,
39
47
  Response,
40
48
  UserResourceCredentials,
@@ -42,8 +50,6 @@ from narada_core.models import (
42
50
  from playwright.async_api import BrowserContext
43
51
  from pydantic import BaseModel
44
52
 
45
- from narada.config import BrowserConfig
46
-
47
53
  _StructuredOutput = TypeVar("_StructuredOutput", bound=BaseModel)
48
54
 
49
55
 
@@ -123,6 +129,7 @@ class BaseBrowserWindow(ABC):
123
129
  attachment: File | None = None,
124
130
  time_zone: str = "America/Los_Angeles",
125
131
  user_resource_credentials: UserResourceCredentials | None = None,
132
+ mcp_servers: list[McpServer] | None = None,
126
133
  variables: dict[str, str] | None = None,
127
134
  callback_url: str | None = None,
128
135
  callback_secret: str | None = None,
@@ -145,6 +152,7 @@ class BaseBrowserWindow(ABC):
145
152
  attachment: File | None = None,
146
153
  time_zone: str = "America/Los_Angeles",
147
154
  user_resource_credentials: UserResourceCredentials | None = None,
155
+ mcp_servers: list[McpServer] | None = None,
148
156
  variables: dict[str, str] | None = None,
149
157
  callback_url: str | None = None,
150
158
  callback_secret: str | None = None,
@@ -166,6 +174,7 @@ class BaseBrowserWindow(ABC):
166
174
  attachment: File | None = None,
167
175
  time_zone: str = "America/Los_Angeles",
168
176
  user_resource_credentials: UserResourceCredentials | None = None,
177
+ mcp_servers: list[McpServer] | None = None,
169
178
  variables: dict[str, str] | None = None,
170
179
  callback_url: str | None = None,
171
180
  callback_secret: str | None = None,
@@ -207,6 +216,10 @@ class BaseBrowserWindow(ABC):
207
216
  body["attachment"] = attachment
208
217
  if user_resource_credentials is not None:
209
218
  body["userResourceCredentials"] = user_resource_credentials
219
+ if mcp_servers is not None:
220
+ body["mcpServers"] = [
221
+ server.model_dump(mode="json") for server in mcp_servers
222
+ ]
210
223
  if variables is not None:
211
224
  body["variables"] = variables
212
225
  if callback_url is not None:
@@ -272,6 +285,7 @@ class BaseBrowserWindow(ABC):
272
285
  output_schema: None = None,
273
286
  attachment: File | None = None,
274
287
  time_zone: str = "America/Los_Angeles",
288
+ mcp_servers: list[McpServer] | None = None,
275
289
  variables: dict[str, str] | None = None,
276
290
  timeout: int = 1000,
277
291
  ) -> AgentResponse[None]: ...
@@ -287,6 +301,7 @@ class BaseBrowserWindow(ABC):
287
301
  output_schema: type[_StructuredOutput],
288
302
  attachment: File | None = None,
289
303
  time_zone: str = "America/Los_Angeles",
304
+ mcp_servers: list[McpServer] | None = None,
290
305
  variables: dict[str, str] | None = None,
291
306
  timeout: int = 1000,
292
307
  ) -> AgentResponse[_StructuredOutput]: ...
@@ -301,6 +316,7 @@ class BaseBrowserWindow(ABC):
301
316
  output_schema: type[BaseModel] | None = None,
302
317
  attachment: File | None = None,
303
318
  time_zone: str = "America/Los_Angeles",
319
+ mcp_servers: list[McpServer] | None = None,
304
320
  variables: dict[str, str] | None = None,
305
321
  timeout: int = 1000,
306
322
  ) -> AgentResponse:
@@ -313,6 +329,7 @@ class BaseBrowserWindow(ABC):
313
329
  output_schema=output_schema,
314
330
  attachment=attachment,
315
331
  time_zone=time_zone,
332
+ mcp_servers=mcp_servers,
316
333
  variables=variables,
317
334
  timeout=timeout,
318
335
  )
@@ -321,7 +338,7 @@ class BaseBrowserWindow(ABC):
321
338
 
322
339
  action_trace_raw = response_content.get("actionTrace")
323
340
  action_trace = (
324
- [ActionTraceItem.model_validate(item) for item in action_trace_raw]
341
+ parse_action_trace(action_trace_raw)
325
342
  if action_trace_raw is not None
326
343
  else None
327
344
  )
@@ -356,14 +373,13 @@ class BaseBrowserWindow(ABC):
356
373
  AgenticSelectorRequest(
357
374
  action=action,
358
375
  selectors=selectors,
359
- response_model=response_model,
360
376
  fallback_operator_query=fallback_operator_query,
361
377
  ),
362
378
  timeout=timeout,
363
379
  )
364
380
 
365
381
  if result is None:
366
- return {"value": None}
382
+ return AgenticSelectorResponse(value=None)
367
383
 
368
384
  return result
369
385
 
@@ -437,6 +453,34 @@ class BaseBrowserWindow(ABC):
437
453
  timeout=timeout,
438
454
  )
439
455
 
456
+ async def get_full_html(self, *, timeout: int | None = None) -> GetFullHtmlResponse:
457
+ """Gets the full HTML content of the current page."""
458
+ return await self._run_extension_action(
459
+ GetFullHtmlRequest(),
460
+ GetFullHtmlResponse,
461
+ timeout=timeout,
462
+ )
463
+
464
+ async def get_simplified_html(
465
+ self, *, timeout: int | None = None
466
+ ) -> GetSimplifiedHtmlResponse:
467
+ """Gets the simplified HTML content of the current page."""
468
+ return await self._run_extension_action(
469
+ GetSimplifiedHtmlRequest(),
470
+ GetSimplifiedHtmlResponse,
471
+ timeout=timeout,
472
+ )
473
+
474
+ async def get_screenshot(
475
+ self, *, timeout: int | None = None
476
+ ) -> GetScreenshotResponse:
477
+ """Takes a screenshot of the current browser window."""
478
+ return await self._run_extension_action(
479
+ GetScreenshotRequest(),
480
+ GetScreenshotResponse,
481
+ timeout=timeout,
482
+ )
483
+
440
484
  @overload
441
485
  async def _run_extension_action(
442
486
  self,
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes