@lydia-agent/core 0.1.0
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.
- package/dist/index.cjs +8089 -0
- package/dist/index.d.cts +3434 -0
- package/dist/index.d.ts +3434 -0
- package/dist/index.js +7965 -0
- package/package.json +40 -0
- package/skills/README.md +17 -0
- package/skills/browser/automation.md +33 -0
- package/skills/docker/management.md +36 -0
- package/skills/git/advanced.md +43 -0
- package/skills/hello-world.md +15 -0
- package/skills/node/management.md +37 -0
- package/skills/system-health.md +15 -0
- package/skills/webapp-testing/LICENSE.txt +202 -0
- package/skills/webapp-testing/SKILL.md +96 -0
- package/skills/webapp-testing/examples/console_logging.py +35 -0
- package/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/skills/webapp-testing/scripts/with_server.py +106 -0
- package/strategies/base-v1.yml +62 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Start one or more servers, wait for them to be ready, run a command, then clean up.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
# Single server
|
|
7
|
+
python scripts/with_server.py --server "npm run dev" --port 5173 -- python automation.py
|
|
8
|
+
python scripts/with_server.py --server "npm start" --port 3000 -- python test.py
|
|
9
|
+
|
|
10
|
+
# Multiple servers
|
|
11
|
+
python scripts/with_server.py \
|
|
12
|
+
--server "cd backend && python server.py" --port 3000 \
|
|
13
|
+
--server "cd frontend && npm run dev" --port 5173 \
|
|
14
|
+
-- python test.py
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import subprocess
|
|
18
|
+
import socket
|
|
19
|
+
import time
|
|
20
|
+
import sys
|
|
21
|
+
import argparse
|
|
22
|
+
|
|
23
|
+
def is_server_ready(port, timeout=30):
|
|
24
|
+
"""Wait for server to be ready by polling the port."""
|
|
25
|
+
start_time = time.time()
|
|
26
|
+
while time.time() - start_time < timeout:
|
|
27
|
+
try:
|
|
28
|
+
with socket.create_connection(('localhost', port), timeout=1):
|
|
29
|
+
return True
|
|
30
|
+
except (socket.error, ConnectionRefusedError):
|
|
31
|
+
time.sleep(0.5)
|
|
32
|
+
return False
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def main():
|
|
36
|
+
parser = argparse.ArgumentParser(description='Run command with one or more servers')
|
|
37
|
+
parser.add_argument('--server', action='append', dest='servers', required=True, help='Server command (can be repeated)')
|
|
38
|
+
parser.add_argument('--port', action='append', dest='ports', type=int, required=True, help='Port for each server (must match --server count)')
|
|
39
|
+
parser.add_argument('--timeout', type=int, default=30, help='Timeout in seconds per server (default: 30)')
|
|
40
|
+
parser.add_argument('command', nargs=argparse.REMAINDER, help='Command to run after server(s) ready')
|
|
41
|
+
|
|
42
|
+
args = parser.parse_args()
|
|
43
|
+
|
|
44
|
+
# Remove the '--' separator if present
|
|
45
|
+
if args.command and args.command[0] == '--':
|
|
46
|
+
args.command = args.command[1:]
|
|
47
|
+
|
|
48
|
+
if not args.command:
|
|
49
|
+
print("Error: No command specified to run")
|
|
50
|
+
sys.exit(1)
|
|
51
|
+
|
|
52
|
+
# Parse server configurations
|
|
53
|
+
if len(args.servers) != len(args.ports):
|
|
54
|
+
print("Error: Number of --server and --port arguments must match")
|
|
55
|
+
sys.exit(1)
|
|
56
|
+
|
|
57
|
+
servers = []
|
|
58
|
+
for cmd, port in zip(args.servers, args.ports):
|
|
59
|
+
servers.append({'cmd': cmd, 'port': port})
|
|
60
|
+
|
|
61
|
+
server_processes = []
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
# Start all servers
|
|
65
|
+
for i, server in enumerate(servers):
|
|
66
|
+
print(f"Starting server {i+1}/{len(servers)}: {server['cmd']}")
|
|
67
|
+
|
|
68
|
+
# Use shell=True to support commands with cd and &&
|
|
69
|
+
process = subprocess.Popen(
|
|
70
|
+
server['cmd'],
|
|
71
|
+
shell=True,
|
|
72
|
+
stdout=subprocess.PIPE,
|
|
73
|
+
stderr=subprocess.PIPE
|
|
74
|
+
)
|
|
75
|
+
server_processes.append(process)
|
|
76
|
+
|
|
77
|
+
# Wait for this server to be ready
|
|
78
|
+
print(f"Waiting for server on port {server['port']}...")
|
|
79
|
+
if not is_server_ready(server['port'], timeout=args.timeout):
|
|
80
|
+
raise RuntimeError(f"Server failed to start on port {server['port']} within {args.timeout}s")
|
|
81
|
+
|
|
82
|
+
print(f"Server ready on port {server['port']}")
|
|
83
|
+
|
|
84
|
+
print(f"\nAll {len(servers)} server(s) ready")
|
|
85
|
+
|
|
86
|
+
# Run the command
|
|
87
|
+
print(f"Running: {' '.join(args.command)}\n")
|
|
88
|
+
result = subprocess.run(args.command)
|
|
89
|
+
sys.exit(result.returncode)
|
|
90
|
+
|
|
91
|
+
finally:
|
|
92
|
+
# Clean up all servers
|
|
93
|
+
print(f"\nStopping {len(server_processes)} server(s)...")
|
|
94
|
+
for i, process in enumerate(server_processes):
|
|
95
|
+
try:
|
|
96
|
+
process.terminate()
|
|
97
|
+
process.wait(timeout=5)
|
|
98
|
+
except subprocess.TimeoutExpired:
|
|
99
|
+
process.kill()
|
|
100
|
+
process.wait()
|
|
101
|
+
print(f"Server {i+1} stopped")
|
|
102
|
+
print("All servers stopped")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
if __name__ == '__main__':
|
|
106
|
+
main()
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
|
|
2
|
+
metadata:
|
|
3
|
+
id: "base-strategy-v1"
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
name: "Lydia Base Strategy"
|
|
6
|
+
description: "The default planning strategy for Lydia, focused on safety and step-by-step execution."
|
|
7
|
+
author: "Lydia Core Team"
|
|
8
|
+
|
|
9
|
+
system:
|
|
10
|
+
role: "You are a strategic planner for an AI Agent."
|
|
11
|
+
goals:
|
|
12
|
+
- "Break down a user's request into executable steps."
|
|
13
|
+
constraints:
|
|
14
|
+
- "Do not hallucinate tools."
|
|
15
|
+
- "Always verify file existence before reading."
|
|
16
|
+
|
|
17
|
+
prompts:
|
|
18
|
+
planning: |
|
|
19
|
+
You are a strategic planner for an AI Agent.
|
|
20
|
+
Your goal is to break down a user's request into executable steps.
|
|
21
|
+
|
|
22
|
+
User Request: "{{task.description}}"
|
|
23
|
+
Intent: {{intent}}
|
|
24
|
+
|
|
25
|
+
{{skillContext}}
|
|
26
|
+
|
|
27
|
+
{{memoryContext}}
|
|
28
|
+
|
|
29
|
+
Available Tools:
|
|
30
|
+
{{tools}}
|
|
31
|
+
|
|
32
|
+
Context Variables:
|
|
33
|
+
- {{cwd}}: Current working directory (absolute path)
|
|
34
|
+
- {{lastResult}}: Output of the previous step
|
|
35
|
+
- Use these variables in arguments to pass data between steps.
|
|
36
|
+
|
|
37
|
+
Output format: JSON object with a "steps" array.
|
|
38
|
+
Each step must have:
|
|
39
|
+
- type: "thought" | "action"
|
|
40
|
+
- description: Clear explanation of the step
|
|
41
|
+
- tool: (Optional, only for "action") Tool name
|
|
42
|
+
- args: (Optional, only for "action") Tool arguments
|
|
43
|
+
|
|
44
|
+
Example:
|
|
45
|
+
{
|
|
46
|
+
"steps": [
|
|
47
|
+
{ "type": "thought", "description": "Check current directory" },
|
|
48
|
+
{ "type": "action", "description": "Get CWD", "tool": "shell_execute", "args": { "command": "pwd" } },
|
|
49
|
+
{ "type": "action", "description": "List files", "tool": "fs_list_directory", "args": { "path": "{{lastResult}}" } }
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
planning:
|
|
54
|
+
temperature: 0.2
|
|
55
|
+
maxSteps: 15
|
|
56
|
+
thinkingProcess: true
|
|
57
|
+
|
|
58
|
+
execution:
|
|
59
|
+
riskTolerance: "low"
|
|
60
|
+
requiresConfirmation:
|
|
61
|
+
- "shell_execute"
|
|
62
|
+
- "fs_write_file"
|