feat: initial project setup with psagentia agent implementation
Add core Python agent with configuration management, environment setup, and deployment documentation. Includes user/agent profiles, startup scripts, and dependency management for the psagentia system.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
from ._main import register_commands as register_commands
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from . import migrate, fine_tunes
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import _SubParsersAction
|
||||
|
||||
|
||||
def register_commands(parser: ArgumentParser, subparser: _SubParsersAction[ArgumentParser]) -> None:
|
||||
migrate.register(subparser)
|
||||
|
||||
namespaced = parser.add_subparsers(title="Tools", help="Convenience client side tools")
|
||||
|
||||
fine_tunes.register(namespaced)
|
||||
@@ -0,0 +1,63 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from typing import TYPE_CHECKING
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from .._models import BaseModel
|
||||
from ...lib._validators import (
|
||||
get_validators,
|
||||
write_out_file,
|
||||
read_any_format,
|
||||
apply_validators,
|
||||
apply_necessary_remediation,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import _SubParsersAction
|
||||
|
||||
|
||||
def register(subparser: _SubParsersAction[ArgumentParser]) -> None:
|
||||
sub = subparser.add_parser("fine_tunes.prepare_data")
|
||||
sub.add_argument(
|
||||
"-f",
|
||||
"--file",
|
||||
required=True,
|
||||
help="JSONL, JSON, CSV, TSV, TXT or XLSX file containing prompt-completion examples to be analyzed."
|
||||
"This should be the local file path.",
|
||||
)
|
||||
sub.add_argument(
|
||||
"-q",
|
||||
"--quiet",
|
||||
required=False,
|
||||
action="store_true",
|
||||
help="Auto accepts all suggestions, without asking for user input. To be used within scripts.",
|
||||
)
|
||||
sub.set_defaults(func=prepare_data, args_model=PrepareDataArgs)
|
||||
|
||||
|
||||
class PrepareDataArgs(BaseModel):
|
||||
file: str
|
||||
|
||||
quiet: bool
|
||||
|
||||
|
||||
def prepare_data(args: PrepareDataArgs) -> None:
|
||||
sys.stdout.write("Analyzing...\n")
|
||||
fname = args.file
|
||||
auto_accept = args.quiet
|
||||
df, remediation = read_any_format(fname)
|
||||
apply_necessary_remediation(None, remediation)
|
||||
|
||||
validators = get_validators()
|
||||
|
||||
assert df is not None
|
||||
|
||||
apply_validators(
|
||||
df,
|
||||
fname,
|
||||
remediation,
|
||||
validators,
|
||||
auto_accept,
|
||||
write_out_file_func=write_out_file,
|
||||
)
|
||||
@@ -0,0 +1,181 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import shutil
|
||||
import tarfile
|
||||
import platform
|
||||
import subprocess
|
||||
from typing import TYPE_CHECKING, List
|
||||
from pathlib import Path
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import httpx
|
||||
|
||||
from .._errors import CLIError, SilentCLIError
|
||||
from .._models import BaseModel
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from argparse import _SubParsersAction
|
||||
|
||||
|
||||
def register(subparser: _SubParsersAction[ArgumentParser]) -> None:
|
||||
sub = subparser.add_parser("migrate")
|
||||
sub.set_defaults(func=migrate, args_model=MigrateArgs, allow_unknown_args=True)
|
||||
|
||||
sub = subparser.add_parser("grit")
|
||||
sub.set_defaults(func=grit, args_model=GritArgs, allow_unknown_args=True)
|
||||
|
||||
|
||||
class GritArgs(BaseModel):
|
||||
# internal
|
||||
unknown_args: List[str] = []
|
||||
|
||||
|
||||
def grit(args: GritArgs) -> None:
|
||||
grit_path = install()
|
||||
|
||||
try:
|
||||
subprocess.check_call([grit_path, *args.unknown_args])
|
||||
except subprocess.CalledProcessError:
|
||||
# stdout and stderr are forwarded by subprocess so an error will already
|
||||
# have been displayed
|
||||
raise SilentCLIError() from None
|
||||
|
||||
|
||||
class MigrateArgs(BaseModel):
|
||||
# internal
|
||||
unknown_args: List[str] = []
|
||||
|
||||
|
||||
def migrate(args: MigrateArgs) -> None:
|
||||
grit_path = install()
|
||||
|
||||
try:
|
||||
subprocess.check_call([grit_path, "apply", "openai", *args.unknown_args])
|
||||
except subprocess.CalledProcessError:
|
||||
# stdout and stderr are forwarded by subprocess so an error will already
|
||||
# have been displayed
|
||||
raise SilentCLIError() from None
|
||||
|
||||
|
||||
# handles downloading the Grit CLI until they provide their own PyPi package
|
||||
|
||||
KEYGEN_ACCOUNT = "custodian-dev"
|
||||
|
||||
|
||||
def _cache_dir() -> Path:
|
||||
xdg = os.environ.get("XDG_CACHE_HOME")
|
||||
if xdg is not None:
|
||||
return Path(xdg)
|
||||
|
||||
return Path.home() / ".cache"
|
||||
|
||||
|
||||
def _debug(message: str) -> None:
|
||||
if not os.environ.get("DEBUG"):
|
||||
return
|
||||
|
||||
sys.stdout.write(f"[DEBUG]: {message}\n")
|
||||
|
||||
|
||||
def install() -> Path:
|
||||
"""Installs the Grit CLI and returns the location of the binary"""
|
||||
if sys.platform == "win32":
|
||||
raise CLIError("Windows is not supported yet in the migration CLI")
|
||||
|
||||
platform = "macos" if sys.platform == "darwin" else "linux"
|
||||
|
||||
dir_name = _cache_dir() / "openai-python"
|
||||
install_dir = dir_name / ".install"
|
||||
target_dir = install_dir / "bin"
|
||||
|
||||
target_path = target_dir / "marzano"
|
||||
temp_file = target_dir / "marzano.tmp"
|
||||
|
||||
if target_path.exists():
|
||||
_debug(f"{target_path} already exists")
|
||||
sys.stdout.flush()
|
||||
return target_path
|
||||
|
||||
_debug(f"Using Grit CLI path: {target_path}")
|
||||
|
||||
target_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if temp_file.exists():
|
||||
temp_file.unlink()
|
||||
|
||||
arch = _get_arch()
|
||||
_debug(f"Using architecture {arch}")
|
||||
|
||||
file_name = f"marzano-{platform}-{arch}"
|
||||
meta_url = f"https://api.keygen.sh/v1/accounts/{KEYGEN_ACCOUNT}/artifacts/{file_name}"
|
||||
|
||||
sys.stdout.write(f"Retrieving Grit CLI metadata from {meta_url}\n")
|
||||
with httpx.Client() as client:
|
||||
response = client.get(meta_url) # pyright: ignore[reportUnknownMemberType]
|
||||
|
||||
data = response.json()
|
||||
errors = data.get("errors")
|
||||
if errors:
|
||||
for error in errors:
|
||||
sys.stdout.write(f"{error}\n")
|
||||
|
||||
raise CLIError("Could not locate Grit CLI binary - see above errors")
|
||||
|
||||
write_manifest(install_dir, data["data"]["relationships"]["release"]["data"]["id"])
|
||||
|
||||
link = data["data"]["links"]["redirect"]
|
||||
_debug(f"Redirect URL {link}")
|
||||
|
||||
download_response = client.get(link) # pyright: ignore[reportUnknownMemberType]
|
||||
with open(temp_file, "wb") as file:
|
||||
for chunk in download_response.iter_bytes():
|
||||
file.write(chunk)
|
||||
|
||||
unpacked_dir = target_dir / "cli-bin"
|
||||
unpacked_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with tarfile.open(temp_file, "r:gz") as archive:
|
||||
archive.extractall(unpacked_dir)
|
||||
|
||||
for item in unpacked_dir.iterdir():
|
||||
item.rename(target_dir / item.name)
|
||||
|
||||
shutil.rmtree(unpacked_dir)
|
||||
os.remove(temp_file)
|
||||
os.chmod(target_path, 0o755)
|
||||
|
||||
sys.stdout.flush()
|
||||
|
||||
return target_path
|
||||
|
||||
|
||||
def _get_arch() -> str:
|
||||
architecture = platform.machine().lower()
|
||||
|
||||
# Map the architecture names to Node.js equivalents
|
||||
arch_map = {
|
||||
"x86_64": "x64",
|
||||
"amd64": "x64",
|
||||
"armv7l": "arm",
|
||||
"aarch64": "arm64",
|
||||
}
|
||||
|
||||
return arch_map.get(architecture, architecture)
|
||||
|
||||
|
||||
def write_manifest(install_path: Path, release: str) -> None:
|
||||
manifest = {
|
||||
"installPath": str(install_path),
|
||||
"binaries": {
|
||||
"marzano": {
|
||||
"name": "marzano",
|
||||
"release": release,
|
||||
},
|
||||
},
|
||||
}
|
||||
manifest_path = Path(install_path) / "manifests.json"
|
||||
with open(manifest_path, "w") as f:
|
||||
json.dump(manifest, f, indent=2)
|
||||
Reference in New Issue
Block a user