@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.
@@ -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"