-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathmain.py
More file actions
92 lines (73 loc) · 2.58 KB
/
main.py
File metadata and controls
92 lines (73 loc) · 2.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import os
from typing import Dict, Optional, TypedDict
import kernel
from loop import sampling_loop
from session import KernelBrowserSession
class QueryInput(TypedDict):
query: str
record_replay: Optional[bool]
class QueryOutput(TypedDict):
result: str
replay_url: Optional[str]
api_key = os.getenv("ANTHROPIC_API_KEY")
if not api_key:
raise ValueError("ANTHROPIC_API_KEY is not set")
app = kernel.App("python-anthropic-cua")
@app.action("cua-task")
async def cua_task(
ctx: kernel.KernelContext,
payload: QueryInput,
) -> QueryOutput:
"""
Process a user query using Anthropic Computer Use with Kernel's browser automation.
Args:
ctx: Kernel context containing invocation information
payload: An object containing:
- query: The task/query string to process
- record_replay: Optional boolean to enable video replay recording
Returns:
A dictionary containing:
- result: The result of the sampling loop as a string
- replay_url: URL to view the replay (if recording was enabled)
"""
if not payload or not payload.get("query"):
raise ValueError("Query is required")
record_replay = payload.get("record_replay", False)
async with KernelBrowserSession(
stealth=True,
record_replay=record_replay,
) as session:
print("Kernel browser live view url:", session.live_view_url)
final_messages = await sampling_loop(
model="claude-sonnet-4-5-20250929",
messages=[
{
"role": "user",
"content": payload["query"],
}
],
api_key=str(api_key),
thinking_budget=1024,
kernel=session.kernel,
session_id=session.session_id,
)
if not final_messages:
raise ValueError("No messages were generated during the sampling loop")
last_message = final_messages[-1]
if not last_message:
raise ValueError(
"Failed to get the last message from the sampling loop"
)
result = ""
if isinstance(last_message.get("content"), str):
result = last_message["content"] # type: ignore[assignment]
else:
result = "".join(
block["text"]
for block in last_message["content"] # type: ignore[index]
if isinstance(block, Dict) and block.get("type") == "text"
)
return {
"result": result,
"replay_url": session.replay_view_url,
}