traw 0.1.1 → 0.1.3

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.
@@ -47,9 +47,13 @@ jobs:
47
47
  ```bash
48
48
  # npm
49
49
  npm install traw
50
+ # npm global
51
+ npm install -g traw
50
52
 
51
53
  # bun
52
54
  bun add traw
55
+ # bun global
56
+ bun add -g traw
53
57
  ```
54
58
 
55
59
  ### Usage
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "traw",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "module": "src/index.ts",
5
5
  "type": "module",
6
6
  "bin": {
package/src/agent.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { Action, AgentConfig, AgentStep, ChatMessage, PageState } from "./types"
2
2
  import { BrowserController } from "./browser"
3
3
  import { MoClient } from "./mo-client"
4
+ import { log } from "./log"
4
5
 
5
6
  const systemPrompt = `You are a browser automation agent. You see the page state and decide what to do next.
6
7
 
@@ -66,11 +67,11 @@ export class Agent {
66
67
  }
67
68
 
68
69
  async run(goal: string): Promise<AgentStep[]> {
69
- console.log(`\n[goal] ${goal}\n`)
70
+ log.info("goal", goal)
70
71
 
71
- console.log("[planning]...")
72
+ log.info("planning", "...")
72
73
  this.plan = await this.createPlan(goal)
73
- console.log("\n" + this.plan + "\n")
74
+ log.plan(this.plan)
74
75
 
75
76
  await this.browser.launch()
76
77
  await this.browser.execute({
@@ -89,17 +90,17 @@ export class Agent {
89
90
  for (let step = 0; step < this.config.maxSteps; step++) {
90
91
  const state = await this.browser.getState()
91
92
 
92
- console.log(`\n--- step ${step + 1} ---`)
93
- console.log(`url: ${state.url}`)
94
- console.log(`title: ${state.title}`)
93
+ log.step(step + 1)
94
+ log.dim("url", state.url)
95
+ log.dim("title", state.title)
95
96
 
96
97
  const decision = await this.think(state)
97
98
 
98
- console.log(`thought: ${decision.thought}`)
99
- console.log(`action: ${decision.action.type} - ${decision.action.reason}`)
99
+ log.thought(decision.thought)
100
+ log.action(decision.action.type, decision.action.reason)
100
101
 
101
102
  const result = await this.browser.execute(decision.action)
102
- console.log(`result: ${result}`)
103
+ log.result(result)
103
104
 
104
105
  this.history.push({
105
106
  timestamp: Date.now(),
@@ -109,7 +110,7 @@ export class Agent {
109
110
  })
110
111
 
111
112
  if (decision.action.type === "done") {
112
- console.log(`\n[complete]`)
113
+ log.done()
113
114
  break
114
115
  }
115
116
 
@@ -118,7 +119,7 @@ export class Agent {
118
119
  } finally {
119
120
  const videoPath = await this.browser.close()
120
121
  if (videoPath) {
121
- console.log(`[video] ${videoPath}`)
122
+ log.info("video", videoPath)
122
123
  }
123
124
  }
124
125
 
package/src/index.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env bun
2
2
  import { Agent } from "./agent"
3
3
  import type { AgentConfig } from "./types"
4
+ import { log } from "./log"
4
5
 
5
6
  const defaultConfig: AgentConfig = {
6
7
  moUrl: "http://localhost:8080",
7
8
  model: "glm-4.7",
8
9
  headless: false,
9
- recordVideo: true,
10
+ recordVideo: false,
10
11
  maxSteps: 20,
11
12
  }
12
13
 
@@ -34,8 +35,8 @@ async function main() {
34
35
  config.headless = true
35
36
  continue
36
37
  }
37
- if (arg === "--no-video") {
38
- config.recordVideo = false
38
+ if (arg === "--video") {
39
+ config.recordVideo = true
39
40
  continue
40
41
  }
41
42
  if (arg.startsWith("--steps=")) {
@@ -53,49 +54,48 @@ async function main() {
53
54
 
54
55
  const goal = goalParts.join(" ")
55
56
  if (!goal) {
56
- console.error("[error] provide a goal: bun run traw run \"your goal\"")
57
+ log.error("provide a goal: bun run traw run \"your goal\"")
57
58
  process.exit(1)
58
59
  }
59
60
 
60
- console.log("[traw] starting agent...")
61
- console.log(` mo: ${config.moUrl}`)
62
- console.log(` headless: ${config.headless}`)
63
- console.log(` video: ${config.recordVideo}`)
64
- console.log(` max steps: ${config.maxSteps}`)
61
+ log.info("traw", "starting agent...")
62
+ log.dim(" mo", config.moUrl)
63
+ log.dim(" headless", String(config.headless))
64
+ log.dim(" video", String(config.recordVideo))
65
+ log.dim(" max steps", String(config.maxSteps))
65
66
 
66
67
  const agent = new Agent(config)
67
68
 
68
69
  try {
69
70
  const history = await agent.run(goal)
70
71
 
71
- console.log("\n[done] steps:", history.length)
72
+ log.done(`steps: ${history.length}`)
72
73
  if (history.length > 0) {
73
74
  const last = history[history.length - 1]
74
- console.log(" final:", last.action.type, "-", last.action.reason)
75
+ log.dim(" final", `${last.action.type} - ${last.action.reason}`)
75
76
  }
76
77
  } catch (err: any) {
77
- console.error("\n[error]", err.message)
78
+ log.error(err.message)
78
79
  process.exit(1)
79
80
  }
80
81
  }
81
82
 
82
83
  function printHelp() {
83
84
  console.log(`
84
- 🌐 traw - AI browser agent
85
+ traw - AI browser agent
85
86
 
86
87
  Usage:
87
88
  traw run "your goal here"
88
- traw run # interactive mode (coming soon)
89
89
 
90
90
  Options:
91
91
  --headless run without visible browser
92
- --no-video disable video recording
92
+ --video enable video recording
93
93
  --steps=N max steps (default: 20)
94
94
  --mo=URL mo server url (default: http://localhost:8080)
95
95
 
96
96
  Examples:
97
97
  traw run "find the weather in Moscow"
98
- traw run "search for bun.js documentation"
98
+ traw run --video "search for bun.js documentation"
99
99
  `)
100
100
  }
101
101
 
package/src/log.ts ADDED
@@ -0,0 +1,50 @@
1
+ // ansi color codes for terminal output
2
+
3
+ const c = {
4
+ reset: "\x1b[0m",
5
+ dim: "\x1b[2m",
6
+ cyan: "\x1b[36m",
7
+ green: "\x1b[32m",
8
+ yellow: "\x1b[33m",
9
+ red: "\x1b[31m",
10
+ magenta: "\x1b[35m",
11
+ blue: "\x1b[34m",
12
+ }
13
+
14
+ export const log = {
15
+ info: (tag: string, msg: string) => {
16
+ console.log(`${c.cyan}[${tag}]${c.reset} ${msg}`)
17
+ },
18
+
19
+ step: (n: number) => {
20
+ console.log(`\n${c.magenta}--- step ${n} ---${c.reset}`)
21
+ },
22
+
23
+ dim: (label: string, value: string) => {
24
+ console.log(`${c.dim}${label}:${c.reset} ${value}`)
25
+ },
26
+
27
+ thought: (msg: string) => {
28
+ console.log(`${c.yellow}thought:${c.reset} ${msg}`)
29
+ },
30
+
31
+ action: (type: string, reason: string) => {
32
+ console.log(`${c.blue}action:${c.reset} ${type} - ${reason}`)
33
+ },
34
+
35
+ result: (msg: string) => {
36
+ console.log(`${c.green}result:${c.reset} ${msg}`)
37
+ },
38
+
39
+ done: (msg?: string) => {
40
+ console.log(`\n${c.green}[done]${c.reset}${msg ? " " + msg : ""}`)
41
+ },
42
+
43
+ error: (msg: string) => {
44
+ console.error(`${c.red}[error]${c.reset} ${msg}`)
45
+ },
46
+
47
+ plan: (text: string) => {
48
+ console.log(`\n${c.dim}${text}${c.reset}\n`)
49
+ },
50
+ }