r2flow-agent 0.3.2__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.
- r2flow_agent-0.3.2/.gitignore +14 -0
- r2flow_agent-0.3.2/LICENSE +21 -0
- r2flow_agent-0.3.2/PKG-INFO +106 -0
- r2flow_agent-0.3.2/README.md +83 -0
- r2flow_agent-0.3.2/install-agent.ps1 +138 -0
- r2flow_agent-0.3.2/pyproject.toml +60 -0
- r2flow_agent-0.3.2/src/r2flow_agent/__init__.py +5 -0
- r2flow_agent-0.3.2/src/r2flow_agent/client.py +350 -0
- r2flow_agent-0.3.2/src/r2flow_agent/config.py +133 -0
- r2flow_agent-0.3.2/src/r2flow_agent/executor.py +567 -0
- r2flow_agent-0.3.2/src/r2flow_agent/main.py +446 -0
- r2flow_agent-0.3.2/src/r2flow_agent/screenshot.py +78 -0
- r2flow_agent-0.3.2/src/r2flow_agent/service.py +379 -0
- r2flow_agent-0.3.2/src/r2flow_agent/streamer.py +123 -0
- r2flow_agent-0.3.2/tests/test_agent_service.py +72 -0
- r2flow_agent-0.3.2/tests/test_command_guards.py +95 -0
- r2flow_agent-0.3.2/tests/test_executor_traversal.py +38 -0
- r2flow_agent-0.3.2/tests/test_packs.py +229 -0
- r2flow_agent-0.3.2/tests/test_screenshot.py +97 -0
- r2flow_agent-0.3.2/tests/test_streamer.py +19 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 2kurosss
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: r2flow-agent
|
|
3
|
+
Version: 0.3.2
|
|
4
|
+
Summary: R2Flow RPA agent - runs on Windows machines and executes processes dispatched by a r2flow-cloud orchestrator
|
|
5
|
+
Project-URL: Homepage, https://github.com/2kurosss/r2flow
|
|
6
|
+
Project-URL: Repository, https://github.com/2kurosss/r2flow
|
|
7
|
+
Project-URL: Issues, https://github.com/2kurosss/r2flow/issues
|
|
8
|
+
Author: 2kurosss
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Python: >=3.11
|
|
12
|
+
Requires-Dist: httpx>=0.27.0
|
|
13
|
+
Requires-Dist: rich>=13.0.0
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Requires-Dist: mypy>=1.18; extra == 'dev'
|
|
16
|
+
Requires-Dist: pytest-asyncio>=1.0; extra == 'dev'
|
|
17
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
18
|
+
Requires-Dist: ruff>=0.12; extra == 'dev'
|
|
19
|
+
Provides-Extra: screenshot
|
|
20
|
+
Requires-Dist: mss>=9; extra == 'screenshot'
|
|
21
|
+
Requires-Dist: pillow>=10; extra == 'screenshot'
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# r2flow-agent
|
|
25
|
+
|
|
26
|
+
Unattended worker that runs on a Windows machine, registers itself with a
|
|
27
|
+
[r2flow-cloud](https://github.com/2kurosss/r2flow) orchestrator,
|
|
28
|
+
polls it for commands, and executes deployed process bundles (Python code)
|
|
29
|
+
in isolated per-process venvs.
|
|
30
|
+
|
|
31
|
+
## One-line install (Windows)
|
|
32
|
+
|
|
33
|
+
Regular PowerShell (it self-elevates and installs Python 3.12 via winget if
|
|
34
|
+
missing):
|
|
35
|
+
|
|
36
|
+
```powershell
|
|
37
|
+
irm https://raw.githubusercontent.com/2kurosss/r2flow/main/packages/agent/install-agent.ps1 | iex
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
With parameters:
|
|
41
|
+
|
|
42
|
+
```powershell
|
|
43
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/2kurosss/r2flow/main/packages/agent/install-agent.ps1))) `
|
|
44
|
+
-Orchestrator https://cloud.example.com -Name prod-1 -JoinToken <TOKEN>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Manual install
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install r2flow-agent
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## Quick start (manual, foreground)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install r2flow-agent
|
|
58
|
+
r2flow-agent --orchestrator http://orch-host:8000 --name my-agent \
|
|
59
|
+
--url http://this-machine:8001
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`--url` must be the address at which the **orchestrator** can reach this
|
|
63
|
+
machine (the orchestrator pushes commands and files to it).
|
|
64
|
+
|
|
65
|
+
## Unattended installation (recommended)
|
|
66
|
+
|
|
67
|
+
UI automation needs an **interactive desktop**, so the agent runs as a
|
|
68
|
+
scheduled task inside a user's log-on session — not as a session-0 service.
|
|
69
|
+
Use a dedicated local user with auto-logon for production agents.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# one command: writes config + creates the scheduled task
|
|
73
|
+
r2flow-agent-service install \
|
|
74
|
+
--orchestrator http://orch-host:8000 \
|
|
75
|
+
--name prod-1 \
|
|
76
|
+
--join-token <AGENT_JOIN_TOKEN> \
|
|
77
|
+
--user "WORKGROUP\\rpa-bot" # optional, default: current user
|
|
78
|
+
|
|
79
|
+
r2flow-agent-service start # launch now
|
|
80
|
+
r2flow-agent-service status # task state
|
|
81
|
+
r2flow-agent-service stop | uninstall
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
What you get:
|
|
85
|
+
|
|
86
|
+
* task trigger **at log on** of the automation user → agent starts with the
|
|
87
|
+
desktop, no manual steps after reboots;
|
|
88
|
+
* Task Scheduler restart policy (up to 999 retries, 1-minute interval) and,
|
|
89
|
+
belt and braces, a crash-restart loop inside the agent with exponential
|
|
90
|
+
backoff (5 s → 60 s, reset after a stable 5-minute run);
|
|
91
|
+
* config at `%LOCALAPPDATA%\r2flow_agent\config.json`, rolling log at
|
|
92
|
+
`%LOCALAPPDATA%\r2flow_agent\agent.log`.
|
|
93
|
+
|
|
94
|
+
Registration honours `AGENT_JOIN_TOKEN` (pre-shared in the orchestrator
|
|
95
|
+
settings) or an admin JWT — whichever you pass with `--join-token`.
|
|
96
|
+
|
|
97
|
+
## Privacy note: failure screenshots
|
|
98
|
+
|
|
99
|
+
On a failed run the agent (with the [screenshot] extra installed) captures
|
|
100
|
+
the **entire virtual screen** — all monitors and every visible window, not
|
|
101
|
+
just the automated app — and uploads it to the orchestrator. Keep this in
|
|
102
|
+
mind on shared/multi-user machines: anything on screen at the moment of
|
|
103
|
+
failure (other apps, browser sessions, passwords) ends up in the cloud.
|
|
104
|
+
|
|
105
|
+
Deploy with the plain r2flow-agent package if screenshots are unwanted;
|
|
106
|
+
the agent runs fine without the extra and simply skips capture.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# r2flow-agent
|
|
2
|
+
|
|
3
|
+
Unattended worker that runs on a Windows machine, registers itself with a
|
|
4
|
+
[r2flow-cloud](https://github.com/2kurosss/r2flow) orchestrator,
|
|
5
|
+
polls it for commands, and executes deployed process bundles (Python code)
|
|
6
|
+
in isolated per-process venvs.
|
|
7
|
+
|
|
8
|
+
## One-line install (Windows)
|
|
9
|
+
|
|
10
|
+
Regular PowerShell (it self-elevates and installs Python 3.12 via winget if
|
|
11
|
+
missing):
|
|
12
|
+
|
|
13
|
+
```powershell
|
|
14
|
+
irm https://raw.githubusercontent.com/2kurosss/r2flow/main/packages/agent/install-agent.ps1 | iex
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
With parameters:
|
|
18
|
+
|
|
19
|
+
```powershell
|
|
20
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/2kurosss/r2flow/main/packages/agent/install-agent.ps1))) `
|
|
21
|
+
-Orchestrator https://cloud.example.com -Name prod-1 -JoinToken <TOKEN>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Manual install
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install r2flow-agent
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Quick start (manual, foreground)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install r2flow-agent
|
|
35
|
+
r2flow-agent --orchestrator http://orch-host:8000 --name my-agent \
|
|
36
|
+
--url http://this-machine:8001
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`--url` must be the address at which the **orchestrator** can reach this
|
|
40
|
+
machine (the orchestrator pushes commands and files to it).
|
|
41
|
+
|
|
42
|
+
## Unattended installation (recommended)
|
|
43
|
+
|
|
44
|
+
UI automation needs an **interactive desktop**, so the agent runs as a
|
|
45
|
+
scheduled task inside a user's log-on session — not as a session-0 service.
|
|
46
|
+
Use a dedicated local user with auto-logon for production agents.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# one command: writes config + creates the scheduled task
|
|
50
|
+
r2flow-agent-service install \
|
|
51
|
+
--orchestrator http://orch-host:8000 \
|
|
52
|
+
--name prod-1 \
|
|
53
|
+
--join-token <AGENT_JOIN_TOKEN> \
|
|
54
|
+
--user "WORKGROUP\\rpa-bot" # optional, default: current user
|
|
55
|
+
|
|
56
|
+
r2flow-agent-service start # launch now
|
|
57
|
+
r2flow-agent-service status # task state
|
|
58
|
+
r2flow-agent-service stop | uninstall
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
What you get:
|
|
62
|
+
|
|
63
|
+
* task trigger **at log on** of the automation user → agent starts with the
|
|
64
|
+
desktop, no manual steps after reboots;
|
|
65
|
+
* Task Scheduler restart policy (up to 999 retries, 1-minute interval) and,
|
|
66
|
+
belt and braces, a crash-restart loop inside the agent with exponential
|
|
67
|
+
backoff (5 s → 60 s, reset after a stable 5-minute run);
|
|
68
|
+
* config at `%LOCALAPPDATA%\r2flow_agent\config.json`, rolling log at
|
|
69
|
+
`%LOCALAPPDATA%\r2flow_agent\agent.log`.
|
|
70
|
+
|
|
71
|
+
Registration honours `AGENT_JOIN_TOKEN` (pre-shared in the orchestrator
|
|
72
|
+
settings) or an admin JWT — whichever you pass with `--join-token`.
|
|
73
|
+
|
|
74
|
+
## Privacy note: failure screenshots
|
|
75
|
+
|
|
76
|
+
On a failed run the agent (with the [screenshot] extra installed) captures
|
|
77
|
+
the **entire virtual screen** — all monitors and every visible window, not
|
|
78
|
+
just the automated app — and uploads it to the orchestrator. Keep this in
|
|
79
|
+
mind on shared/multi-user machines: anything on screen at the moment of
|
|
80
|
+
failure (other apps, browser sessions, passwords) ends up in the cloud.
|
|
81
|
+
|
|
82
|
+
Deploy with the plain r2flow-agent package if screenshots are unwanted;
|
|
83
|
+
the agent runs fine without the extra and simply skips capture.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#requires -Version 5.1
|
|
2
|
+
<#
|
|
3
|
+
R2Flow agent one-line installer (Windows).
|
|
4
|
+
|
|
5
|
+
Usage (regular PowerShell, elevated not required - it will self-elevate):
|
|
6
|
+
|
|
7
|
+
irm https://raw.githubusercontent.com/2kurosss/r2flow/main/packages/agent/install-agent.ps1 | iex
|
|
8
|
+
|
|
9
|
+
or with parameters:
|
|
10
|
+
|
|
11
|
+
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/2kurosss/r2flow/main/packages/agent/install-agent.ps1))) `
|
|
12
|
+
-Orchestrator https://cloud.example.com -Name prod-1 -JoinToken <TOKEN>
|
|
13
|
+
#>
|
|
14
|
+
param(
|
|
15
|
+
[string]$Orchestrator = "",
|
|
16
|
+
[string]$Name = "",
|
|
17
|
+
[string]$JoinToken = "",
|
|
18
|
+
[string]$AgentUrl = "",
|
|
19
|
+
[string]$User = "",
|
|
20
|
+
[string]$Python = "",
|
|
21
|
+
# Supply-chain pinning: point this at a release tag instead of master
|
|
22
|
+
# (e.g. https://raw.githubusercontent.com/2kurosss/r2flow/v0.2.1/install-agent.ps1)
|
|
23
|
+
[string]$RepoUrl = "https://raw.githubusercontent.com/2kurosss/r2flow/main/packages/agent/install-agent.ps1"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
$ErrorActionPreference = "Stop"
|
|
27
|
+
$VenvDir = Join-Path $env:LOCALAPPDATA "r2flow-agent\venv"
|
|
28
|
+
|
|
29
|
+
function Test-Admin {
|
|
30
|
+
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
31
|
+
(New-Object Security.Principal.WindowsPrincipal($id)).IsInRole(
|
|
32
|
+
[Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function Find-Python {
|
|
36
|
+
if ($Python -and (Test-Path $Python)) { return $Python }
|
|
37
|
+
$cmd = Get-Command python -ErrorAction SilentlyContinue
|
|
38
|
+
if ($cmd) {
|
|
39
|
+
$v = & python -c "import sys; print('%d.%d' % sys.version_info[:2])" 2>$null
|
|
40
|
+
if ($v -and [version]$v -ge [version]"3.11") { return $cmd.Source }
|
|
41
|
+
}
|
|
42
|
+
$py = Get-Command py -ErrorAction SilentlyContinue
|
|
43
|
+
if ($py) {
|
|
44
|
+
$v = & py -3 -c "import sys; print('%d.%d' % sys.version_info[:2])" 2>$null
|
|
45
|
+
if ($v -and [version]$v -ge [version]"3.11") { return "py" }
|
|
46
|
+
}
|
|
47
|
+
return ""
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# ---------------------------------------------------------------- elevate
|
|
51
|
+
if (-not (Test-Admin)) {
|
|
52
|
+
Write-Host "Not running as administrator - relaunching elevated..."
|
|
53
|
+
$tmp = Join-Path $env:TEMP "r2flow-agent-install.ps1"
|
|
54
|
+
if ($MyInvocation.MyCommand.Path -and (Test-Path $MyInvocation.MyCommand.Path)) {
|
|
55
|
+
# Elevated pass must run the exact copy the user inspected - never a
|
|
56
|
+
# fresh (possibly different) download from the network.
|
|
57
|
+
Copy-Item $MyInvocation.MyCommand.Path $tmp -Force
|
|
58
|
+
} else {
|
|
59
|
+
# irm|iex entry: no file on disk - pin to whatever RepoUrl was set to.
|
|
60
|
+
Invoke-WebRequest -UseBasicParsing -Uri $RepoUrl -OutFile $tmp
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Rebuild the invocation as an encoded command: values starting with "-"
|
|
64
|
+
# (join tokens are base64-ish) cannot be passed as bare -File arguments.
|
|
65
|
+
function Esc([string]$s) { return "'" + $s.Replace("'", "''") + "'" }
|
|
66
|
+
$inner = "& '$tmp'"
|
|
67
|
+
foreach ($p in @("Orchestrator", "Name", "JoinToken", "AgentUrl", "User", "Python")) {
|
|
68
|
+
$val = Get-Variable -Name $p -ValueOnly
|
|
69
|
+
if ($val) { $inner += " -$p $(Esc $val)" }
|
|
70
|
+
}
|
|
71
|
+
$enc = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($inner))
|
|
72
|
+
$proc = Start-Process powershell -Verb RunAs -Wait -PassThru -ArgumentList @(
|
|
73
|
+
"-NoProfile", "-ExecutionPolicy", "Bypass", "-EncodedCommand", $enc)
|
|
74
|
+
exit $proc.ExitCode
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
Write-Host "=== R2Flow agent installer ==="
|
|
78
|
+
|
|
79
|
+
# ---------------------------------------------------------------- orchestrator
|
|
80
|
+
if (-not $Orchestrator) {
|
|
81
|
+
$Orchestrator = Read-Host "Orchestrator URL (e.g. https://cloud.example.com)"
|
|
82
|
+
}
|
|
83
|
+
$Orchestrator = $Orchestrator.TrimEnd("/")
|
|
84
|
+
|
|
85
|
+
if (-not $Name) {
|
|
86
|
+
$hostLabel = $env:COMPUTERNAME.ToLower() -replace "[^a-z0-9-]", "-"
|
|
87
|
+
$Name = "agent-$hostLabel"
|
|
88
|
+
}
|
|
89
|
+
Write-Host "Orchestrator: $Orchestrator"
|
|
90
|
+
Write-Host "Agent name: $Name"
|
|
91
|
+
|
|
92
|
+
# ---------------------------------------------------------------- python
|
|
93
|
+
$pyExe = Find-Python
|
|
94
|
+
if (-not $pyExe) {
|
|
95
|
+
Write-Host "Python 3.11+ not found - installing via winget..."
|
|
96
|
+
winget install --id Python.Python.3.12 --silent --accept-package-agreements --accept-source-agreements
|
|
97
|
+
if ($LASTEXITCODE -ne 0) { throw "winget failed to install Python; install it manually from https://python.org" }
|
|
98
|
+
# winget adds Python to the machine PATH; pick it up for this session
|
|
99
|
+
$env:PATH = [Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" +
|
|
100
|
+
[Environment]::GetEnvironmentVariable("PATH", "User")
|
|
101
|
+
$pyExe = Find-Python
|
|
102
|
+
if (-not $pyExe) { throw "Python installed but not found - reopen the terminal and retry" }
|
|
103
|
+
}
|
|
104
|
+
Write-Host "Python: $pyExe"
|
|
105
|
+
|
|
106
|
+
# ---------------------------------------------------------------- venv
|
|
107
|
+
New-Item -ItemType Directory -Force -Path (Split-Path $VenvDir) | Out-Null
|
|
108
|
+
if (-not (Test-Path "$VenvDir\Scripts\python.exe")) {
|
|
109
|
+
Write-Host "Creating venv at $VenvDir ..."
|
|
110
|
+
& $pyExe -m venv $VenvDir
|
|
111
|
+
if ($LASTEXITCODE -ne 0) { throw "venv creation failed" }
|
|
112
|
+
}
|
|
113
|
+
Write-Host "Installing r2flow-agent[screenshot] (PyPI)..."
|
|
114
|
+
& "$VenvDir\Scripts\python.exe" -m pip install --upgrade pip --quiet
|
|
115
|
+
& "$VenvDir\Scripts\python.exe" -m pip install --upgrade "r2flow-agent[screenshot]" --quiet
|
|
116
|
+
if ($LASTEXITCODE -ne 0) { throw "pip install r2flow-agent failed" }
|
|
117
|
+
|
|
118
|
+
# ---------------------------------------------------------------- register
|
|
119
|
+
$svc = "$VenvDir\Scripts\r2flow-agent-service.exe"
|
|
120
|
+
if (-not (Test-Path $svc)) { $svc = "$VenvDir\Scripts\r2flow-agent-service.bat" }
|
|
121
|
+
|
|
122
|
+
$installArgs = @("install", "--orchestrator", $Orchestrator, "--name", $Name)
|
|
123
|
+
if ($AgentUrl) { $installArgs += @("--url", $AgentUrl) }
|
|
124
|
+
if ($JoinToken) { $installArgs += "--join-token=$JoinToken" }
|
|
125
|
+
if ($User) { $installArgs += @("--user", $User) }
|
|
126
|
+
|
|
127
|
+
& $svc @installArgs
|
|
128
|
+
if ($LASTEXITCODE -ne 0) { throw "r2flow-agent-service install failed (exit $LASTEXITCODE)" }
|
|
129
|
+
|
|
130
|
+
Write-Host "Starting the agent..."
|
|
131
|
+
& $svc start
|
|
132
|
+
|
|
133
|
+
Write-Host ""
|
|
134
|
+
Write-Host "=== Done ==="
|
|
135
|
+
Write-Host "Agent: $Name"
|
|
136
|
+
Write-Host "Config: $env:LOCALAPPDATA\r2flow_agent\config.json"
|
|
137
|
+
Write-Host "Log: $env:LOCALAPPDATA\r2flow_agent\agent.log"
|
|
138
|
+
Write-Host "It starts automatically at logon. Check it in the orchestrator web UI."
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "r2flow-agent"
|
|
7
|
+
version = "0.3.2"
|
|
8
|
+
description = "R2Flow RPA agent - runs on Windows machines and executes processes dispatched by a r2flow-cloud orchestrator"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
authors = [{ name = "2kurosss" }]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"httpx>=0.27.0",
|
|
15
|
+
"rich>=13.0.0",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.optional-dependencies]
|
|
19
|
+
screenshot = [
|
|
20
|
+
"mss>=9",
|
|
21
|
+
"Pillow>=10",
|
|
22
|
+
]
|
|
23
|
+
dev = [
|
|
24
|
+
"pytest>=8",
|
|
25
|
+
"pytest-asyncio>=1.0",
|
|
26
|
+
"ruff>=0.12",
|
|
27
|
+
"mypy>=1.18",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://github.com/2kurosss/r2flow"
|
|
32
|
+
Repository = "https://github.com/2kurosss/r2flow"
|
|
33
|
+
Issues = "https://github.com/2kurosss/r2flow/issues"
|
|
34
|
+
|
|
35
|
+
[project.scripts]
|
|
36
|
+
r2flow-agent = "r2flow_agent.main:main"
|
|
37
|
+
r2flow-agent-service = "r2flow_agent.service:main"
|
|
38
|
+
|
|
39
|
+
[tool.hatch.build.targets.wheel]
|
|
40
|
+
packages = ["src/r2flow_agent"]
|
|
41
|
+
|
|
42
|
+
[tool.pytest.ini_options]
|
|
43
|
+
testpaths = ["tests"]
|
|
44
|
+
asyncio_mode = "auto"
|
|
45
|
+
|
|
46
|
+
[tool.ruff]
|
|
47
|
+
line-length = 100
|
|
48
|
+
target-version = "py311"
|
|
49
|
+
|
|
50
|
+
[tool.ruff.lint]
|
|
51
|
+
select = ["E", "F", "I", "N", "UP", "B", "A", "C4", "SIM"]
|
|
52
|
+
# B008 (function call in default) is the idiomatic argparse/click pattern.
|
|
53
|
+
ignore = ["B008"]
|
|
54
|
+
|
|
55
|
+
[tool.mypy]
|
|
56
|
+
python_version = "3.11"
|
|
57
|
+
|
|
58
|
+
[[tool.mypy.overrides]]
|
|
59
|
+
module = ["mss", "mss.*", "PIL", "PIL.*"]
|
|
60
|
+
ignore_missing_imports = true
|