已合并
# 目录调整,增加foundation工程 #7
曹玉哲创建于 3月18日
# 目录调整,增加foundation工程 #7
已合并
共 95 个文件变更+146-756
| @@ -114,3 +114,5 @@ htmlcov/ | |||
| 114 | .mypy_cache/ | 114 | .mypy_cache/ |
| 115 | .dmypy.json | 115 | .dmypy.json |
| 116 | dmypy.json | 116 | dmypy.json |
| 117 | + | ||
| 118 | +.trae | ||
| @@ -12,11 +12,9 @@ from pathlib import Path | |||
| 12 | import click | 12 | import click |
| 13 | from dotenv import load_dotenv | 13 | from dotenv import load_dotenv |
| 14 | 14 | ||
| 15 | -from openjiuwen_runtime.management.sdk import ( | 15 | +from openjiuwen_runtime.management.manager import DeploymentManager |
| 16 | - DeploymentManager, | 16 | +from openjiuwen_runtime.management.models.enums import DeploymentType, DeploymentStatus |
| 17 | - DeploymentType, | 17 | +from openjiuwen_runtime.foundation.db.sqlite_handler import SQLiteHandler |
| 18 | - DeploymentStatus, | ||
| 19 | -) | ||
| 20 | 18 | ||
| 21 | # 配置日志输出 | 19 | # 配置日志输出 |
| 22 | logging.basicConfig( | 20 | logging.basicConfig( |
| @@ -38,7 +36,21 @@ def cli(ctx): | |||
| 38 | ctx.ensure_object(dict) | 36 | ctx.ensure_object(dict) |
| 39 | 37 | ||
| 40 | # 从环境变量读取配置 | 38 | # 从环境变量读取配置 |
| 41 | - ctx.obj["manager"] = DeploymentManager() | 39 | + db_handler = SQLiteHandler('deployments.db') |
| 40 | + manager = DeploymentManager(db_handler) | ||
| 41 | + ctx.obj["manager"] = manager | ||
| 42 | + ctx.obj["db_handler"] = db_handler | ||
| 43 | + | ||
| 44 | + # 初始化 manager | ||
| 45 | + asyncio.run(manager.initialize()) | ||
| 46 | + | ||
| 47 | + | ||
| 48 | + | ||
| 49 | + | ||
| 50 | +def cleanup(ctx, result, **kwargs): | ||
| 51 | + """清理资源""" | ||
| 52 | + if "manager" in ctx.obj: | ||
| 53 | + asyncio.run(ctx.obj["manager"].shutdown()) | ||
| 42 | 54 | ||
| 43 | 55 | ||
| 44 | # ==================== Agent 命令 ==================== | 56 | # ==================== Agent 命令 ==================== |
| @@ -69,8 +81,9 @@ def deploy(ctx, python_file_path, name, port): | |||
| 69 | 81 | ||
| 70 | async def _deploy(): | 82 | async def _deploy(): |
| 71 | result = await manager.deploy_agent( | 83 | result = await manager.deploy_agent( |
| 72 | - python_file_path=python_file_path, | ||
| 73 | name=name, | 84 | name=name, |
| 85 | + version="1.0.0", | ||
| 86 | + python_file_path=python_file_path, | ||
| 74 | port=port, | 87 | port=port, |
| 75 | ) | 88 | ) |
| 76 | click.echo(json.dumps(result, indent=2, ensure_ascii=False)) | 89 | click.echo(json.dumps(result, indent=2, ensure_ascii=False)) |
| @@ -88,7 +101,7 @@ def list(ctx, status): | |||
| 88 | async def _list(): | 101 | async def _list(): |
| 89 | deployments = await manager.list_deployments( | 102 | deployments = await manager.list_deployments( |
| 90 | deployment_type=DeploymentType.AGENT, | 103 | deployment_type=DeploymentType.AGENT, |
| 91 | - status=DeploymentStatus(status) if status else None, | 104 | + deployment_status=DeploymentStatus(status) if status else None, |
| 92 | ) | 105 | ) |
| 93 | 106 | ||
| 94 | if not deployments: | 107 | if not deployments: |
| @@ -172,8 +185,9 @@ def deploy(ctx, python_file_path, name, port): | |||
| 172 | 185 | ||
| 173 | async def _deploy(): | 186 | async def _deploy(): |
| 174 | result = await manager.deploy_plugin( | 187 | result = await manager.deploy_plugin( |
| 175 | - python_file_path=python_file_path, | ||
| 176 | name=name, | 188 | name=name, |
| 189 | + version="1.0.0", | ||
| 190 | + python_file_path=python_file_path, | ||
| 177 | port=port, | 191 | port=port, |
| 178 | ) | 192 | ) |
| 179 | click.echo(json.dumps(result, indent=2, ensure_ascii=False)) | 193 | click.echo(json.dumps(result, indent=2, ensure_ascii=False)) |
| @@ -191,7 +205,7 @@ def list(ctx, status): | |||
| 191 | async def _list(): | 205 | async def _list(): |
| 192 | deployments = await manager.list_deployments( | 206 | deployments = await manager.list_deployments( |
| 193 | deployment_type=DeploymentType.PLUGIN, | 207 | deployment_type=DeploymentType.PLUGIN, |
| 194 | - status=DeploymentStatus(status) if status else None, | 208 | + deployment_status=DeploymentStatus(status) if status else None, |
| 195 | ) | 209 | ) |
| 196 | 210 | ||
| 197 | if not deployments: | 211 | if not deployments: |
| @@ -3,7 +3,7 @@ requires = ["setuptools>=61.0", "wheel"] | |||
| 3 | build-backend = "setuptools.build_meta" | 3 | build-backend = "setuptools.build_meta" |
| 4 | 4 | ||
| 5 | [project] | 5 | [project] |
| 6 | -name = "agent-runtime-manager-cli" | 6 | +name = "agent-runtime-cli" |
| 7 | version = "0.1.0" | 7 | version = "0.1.0" |
| 8 | description = "Agent Runtime Manager CLI" | 8 | description = "Agent Runtime Manager CLI" |
| 9 | requires-python = ">=3.11.4" | 9 | requires-python = ">=3.11.4" |
| @@ -12,8 +12,9 @@ dependencies = [ | |||
| 12 | "python-dotenv>=1.0.0", | 12 | "python-dotenv>=1.0.0", |
| 13 | "fastapi>=0.100.0", | 13 | "fastapi>=0.100.0", |
| 14 | "uvicorn>=0.23.0", | 14 | "uvicorn>=0.23.0", |
| 15 | - # SDK dependency (local path) | 15 | + # local dependencies |
| 16 | - "openjiuwen-runtime-management-sdk @ file:///${PROJECT_ROOT}/../sdk", | 16 | + "openjiuwen-runtime-management @ file://../management", |
| 17 | + "openjiuwen-runtime-foundation @ file://../foundation", | ||
| 17 | ] | 18 | ] |
| 18 | 19 | ||
| 19 | [tool.uv] | 20 | [tool.uv] |
| @@ -27,11 +28,10 @@ dev = [ | |||
| 27 | [[tool.uv.index]] | 28 | [[tool.uv.index]] |
| 28 | url = "https://mirrors.aliyun.com/pypi/simple/" | 29 | url = "https://mirrors.aliyun.com/pypi/simple/" |
| 29 | 30 | ||
| 30 | -[tool.setuptools] | 31 | +[tool.setuptools.packages.find] |
| 31 | -packages = ["openjiuwen_runtime.cli"] | 32 | +where = ["."] |
| 32 | - | 33 | +exclude = ["*.egg-info", "tests"] |
| 33 | -[tool.setuptools.package-dir] | 34 | +include = ["openjiuwen_runtime*"] |
| 34 | -"openjiuwen_runtime.cli" = "src" | ||
| 35 | 35 | ||
| 36 | [project.scripts] | 36 | [project.scripts] |
| 37 | -agent-runtime-manager = "openjiuwen_runtime.cli.main:cli" | 37 | +openjiuwen = "openjiuwen_runtime.cli.main:cli" |
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/foundation/__init__.py→foundation/openjiuwen_runtime/foundation/__init__.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/foundation/config/logging.yaml→foundation/openjiuwen_runtime/foundation/config/logging.yaml+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/db/__init__.py→foundation/openjiuwen_runtime/foundation/db/__init__.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/db/handler.py→foundation/openjiuwen_runtime/foundation/db/handler.py+1-1文件内容审核中,请稍后刷新重试
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/db/mysql_handler.py→foundation/openjiuwen_runtime/foundation/db/mysql_handler.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/db/redis_handler.py→foundation/openjiuwen_runtime/foundation/db/redis_handler.py+1-1
| @@ -5,7 +5,7 @@ from typing import Optional, Any | |||
| 5 | import redis.asyncio as redis | 5 | import redis.asyncio as redis |
| 6 | 6 | ||
| 7 | from .handler import DBHandler | 7 | from .handler import DBHandler |
| 8 | -from ..models.table_def import TableDefinition | 8 | +from .table_def import TableDefinition |
| 9 | 9 | ||
| 10 | 10 | ||
| 11 | class RedisHandler(DBHandler): | 11 | class RedisHandler(DBHandler): |
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/db/sqlalchemy_handler.py→foundation/openjiuwen_runtime/foundation/db/sqlalchemy_handler.py+1-1
| @@ -8,7 +8,7 @@ from sqlalchemy.orm import DeclarativeBase | |||
| 8 | from sqlalchemy import select, update, delete | 8 | from sqlalchemy import select, update, delete |
| 9 | 9 | ||
| 10 | from .handler import DBHandler | 10 | from .handler import DBHandler |
| 11 | -from ..models.table_def import TableDefinition, ColumnDefinition | 11 | +from .table_def import TableDefinition, ColumnDefinition |
| 12 | 12 | ||
| 13 | logger = logging.getLogger(__name__) | 13 | logger = logging.getLogger(__name__) |
| 14 | 14 | ||
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/db/sqlite_handler.py→foundation/openjiuwen_runtime/foundation/db/sqlite_handler.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/models/table_def.py→foundation/openjiuwen_runtime/foundation/db/table_def.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/foundation/docker_utils.py→foundation/openjiuwen_runtime/foundation/docker_utils.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/foundation/log/__init__.py→foundation/openjiuwen_runtime/foundation/log/__init__.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/foundation/log/config.py→foundation/openjiuwen_runtime/foundation/log/config.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/foundation/log/handler.py→foundation/openjiuwen_runtime/foundation/log/handler.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/foundation/packaging.py→foundation/openjiuwen_runtime/foundation/packaging.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/foundation/venv_manager.py→foundation/openjiuwen_runtime/foundation/venv_manager.py+0-0
文件重命名但无更改。
| @@ -3,7 +3,7 @@ requires = ["setuptools>=61.0", "wheel"] | |||
| 3 | build-backend = "setuptools.build_meta" | 3 | build-backend = "setuptools.build_meta" |
| 4 | 4 | ||
| 5 | [project] | 5 | [project] |
| 6 | -name = "openjiuwen-runtime-management-sdk" | 6 | +name = "openjiuwen-runtime-foundation" |
| 7 | version = "0.1.0" | 7 | version = "0.1.0" |
| 8 | description = "OpenJiuwen Runtime" | 8 | description = "OpenJiuwen Runtime" |
| 9 | requires-python = ">=3.11.4" | 9 | requires-python = ">=3.11.4" |
| @@ -43,12 +43,11 @@ dev = [ | |||
| 43 | [[tool.uv.index]] | 43 | [[tool.uv.index]] |
| 44 | url = "https://mirrors.aliyun.com/pypi/simple/" | 44 | url = "https://mirrors.aliyun.com/pypi/simple/" |
| 45 | 45 | ||
| 46 | -[tool.setuptools] | 46 | +[tool.setuptools.packages.find] |
| 47 | -packages = ["openjiuwen_runtime.management.sdk"] | 47 | +where = ["."] |
| 48 | - | 48 | +exclude = ["*.egg-info", "tests"] |
| 49 | -[tool.setuptools.package-dir] | 49 | +include = ["openjiuwen_runtime*"] |
| 50 | -"openjiuwen_runtime.management.sdk" = "openjiuwen_runtime/management/sdk" | 50 | + |
| 51 | - | ||
| 52 | [tool.pytest.ini_options] | 51 | [tool.pytest.ini_options] |
| 53 | testpaths = ["tests"] | 52 | testpaths = ["tests"] |
| 54 | pythonpath = ["."] | 53 | pythonpath = ["."] |
Rsrc/manager/sdk/tests/resources/config/max_bytes_logging.yaml→foundation/tests/resources/config/max_bytes_logging.yaml+0-0
文件重命名但无更改。
Rsrc/manager/sdk/tests/unit_tests/test_sqlite_handler.py→foundation/tests/unit_tests/test_sqlite_handler.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/__init__.py→management/openjiuwen_runtime/management/__init__.py+3-3
| @@ -3,7 +3,7 @@ | |||
| 3 | from .manager import DeploymentManager, DeployMode | 3 | from .manager import DeploymentManager, DeployMode |
| 4 | from .models.enums import DeploymentType, DeploymentStatus | 4 | from .models.enums import DeploymentType, DeploymentStatus |
| 5 | from .models.schemas import DeploymentInfo, DEPLOYMENT_TABLE_NAME, DeploymentFields | 5 | from .models.schemas import DeploymentInfo, DEPLOYMENT_TABLE_NAME, DeploymentFields |
| 6 | -from .db.handler import DBHandler | 6 | +from openjiuwen_runtime.foundation.db.handler import DBHandler |
| 7 | from .deployments import ( | 7 | from .deployments import ( |
| 8 | CommonParams, | 8 | CommonParams, |
| 9 | DeployContext, | 9 | DeployContext, |
| @@ -30,8 +30,8 @@ from .deployments import ( | |||
| 30 | K8sStrategy, | 30 | K8sStrategy, |
| 31 | ) | 31 | ) |
| 32 | 32 | ||
| 33 | -from .db.sqlite_handler import SQLiteHandler | 33 | +from openjiuwen_runtime.foundation.db.sqlite_handler import SQLiteHandler |
| 34 | -from .db.mysql_handler import MySQLHandler | 34 | +from openjiuwen_runtime.foundation.db.mysql_handler import MySQLHandler |
| 35 | 35 | ||
| 36 | __all__ = [ | 36 | __all__ = [ |
| 37 | # Manager | 37 | # Manager |
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/__init__.py→management/openjiuwen_runtime/management/deployments/__init__.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/base/__init__.py→management/openjiuwen_runtime/management/deployments/base/__init__.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/base/deployer.py→management/openjiuwen_runtime/management/deployments/base/deployer.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/base/models.py→management/openjiuwen_runtime/management/deployments/base/models.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/base/strategy.py→management/openjiuwen_runtime/management/deployments/base/strategy.py+1-1
| @@ -9,7 +9,7 @@ from ...db.handler import DBHandler | |||
| 9 | from .models import DeployContext, DeployResult | 9 | from .models import DeployContext, DeployResult |
| 10 | from .deployer import Deployer | 10 | from .deployer import Deployer |
| 11 | from ...models.enums import DeploymentStatus | 11 | from ...models.enums import DeploymentStatus |
| 12 | -from ...models.table_def import TableDefinition | 12 | +from openjiuwen_runtime.foundation.db.table_def import TableDefinition |
| 13 | from ...models.schemas import DEPLOYMENT_TABLE_NAME, DeploymentFields | 13 | from ...models.schemas import DEPLOYMENT_TABLE_NAME, DeploymentFields |
| 14 | 14 | ||
| 15 | T = TypeVar("T") | 15 | T = TypeVar("T") |
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/docker/__init__.py→management/openjiuwen_runtime/management/deployments/docker/__init__.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/docker/deployer.py→management/openjiuwen_runtime/management/deployments/docker/deployer.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/docker/models.py→management/openjiuwen_runtime/management/deployments/docker/models.py+1-1文件内容审核中,请稍后刷新重试
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/docker/strategy.py→management/openjiuwen_runtime/management/deployments/docker/strategy.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/k8s/__init__.py→management/openjiuwen_runtime/management/deployments/k8s/__init__.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/k8s/deployer.py→management/openjiuwen_runtime/management/deployments/k8s/deployer.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/k8s/models.py→management/openjiuwen_runtime/management/deployments/k8s/models.py+1-1
| @@ -6,7 +6,7 @@ from typing import Any, Optional | |||
| 6 | 6 | ||
| 7 | from pydantic import BaseModel, Field | 7 | from pydantic import BaseModel, Field |
| 8 | 8 | ||
| 9 | -from ...models.table_def import TableDefinition, ColumnDefinition, IndexDefinition | 9 | +from openjiuwen_runtime.foundation.db.table_def import TableDefinition, ColumnDefinition, IndexDefinition |
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | 12 | ||
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/k8s/strategy.py→management/openjiuwen_runtime/management/deployments/k8s/strategy.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/subprocess/__init__.py→management/openjiuwen_runtime/management/deployments/subprocess/__init__.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/subprocess/deployer.py→management/openjiuwen_runtime/management/deployments/subprocess/deployer.py+1-1
| @@ -18,7 +18,7 @@ from typing import Dict, Optional | |||
| 18 | from ..base.deployer import Deployer | 18 | from ..base.deployer import Deployer |
| 19 | from ..base.models import DeployContext, DeployResult | 19 | from ..base.models import DeployContext, DeployResult |
| 20 | from .models import SubprocessParams | 20 | from .models import SubprocessParams |
| 21 | -from ...foundation.venv_manager import VirtualEnvironmentManager | 21 | +from openjiuwen_runtime.foundation.venv_manager import VirtualEnvironmentManager |
| 22 | from ...models.enums import DeploymentStatus | 22 | from ...models.enums import DeploymentStatus |
| 23 | 23 | ||
| 24 | logger = logging.getLogger(__name__) | 24 | logger = logging.getLogger(__name__) |
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/subprocess/models.py→management/openjiuwen_runtime/management/deployments/subprocess/models.py+1-1文件内容审核中,请稍后刷新重试
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/deployments/subprocess/strategy.py→management/openjiuwen_runtime/management/deployments/subprocess/strategy.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/manager.py→management/openjiuwen_runtime/management/manager.py+2-2
| @@ -4,7 +4,7 @@ from datetime import datetime | |||
| 4 | from enum import Enum | 4 | from enum import Enum |
| 5 | from typing import Optional, Any | 5 | from typing import Optional, Any |
| 6 | 6 | ||
| 7 | -from .db.handler import DBHandler | 7 | +from openjiuwen_runtime.foundation.db.handler import DBHandler |
| 8 | from .models.enums import DeploymentType, DeploymentStatus | 8 | from .models.enums import DeploymentType, DeploymentStatus |
| 9 | from .models.schemas import ( | 9 | from .models.schemas import ( |
| 10 | DeploymentInfo, | 10 | DeploymentInfo, |
| @@ -12,7 +12,7 @@ from .models.schemas import ( | |||
| 12 | DEPLOYMENT_TABLE_NAME, | 12 | DEPLOYMENT_TABLE_NAME, |
| 13 | DeploymentFields, | 13 | DeploymentFields, |
| 14 | ) | 14 | ) |
| 15 | -from .models.table_def import TableDefinition, ColumnDefinition, IndexDefinition | 15 | +from openjiuwen_runtime.foundation.db.table_def import TableDefinition, ColumnDefinition, IndexDefinition |
| 16 | from .deployments import ( | 16 | from .deployments import ( |
| 17 | BaseDeploymentStrategy, | 17 | BaseDeploymentStrategy, |
| 18 | ProcessInfo, | 18 | ProcessInfo, |
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/models/__init__.py→management/openjiuwen_runtime/management/models/__init__.py+1-1
| @@ -7,7 +7,7 @@ from .schemas import ( | |||
| 7 | DEPLOYMENT_TABLE_NAME, | 7 | DEPLOYMENT_TABLE_NAME, |
| 8 | DeploymentFields, | 8 | DeploymentFields, |
| 9 | ) | 9 | ) |
| 10 | -from .table_def import TableDefinition, ColumnDefinition, IndexDefinition | 10 | +from openjiuwen_runtime.foundation.db.table_def import TableDefinition, ColumnDefinition, IndexDefinition |
| 11 | 11 | ||
| 12 | __all__ = [ | 12 | __all__ = [ |
| 13 | "DeploymentType", | 13 | "DeploymentType", |
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/models/enums.py→management/openjiuwen_runtime/management/models/enums.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/manager/sdk/openjiuwen_runtime/management/sdk/models/schemas.py→management/openjiuwen_runtime/management/models/schemas.py+0-0文件内容审核中,请稍后刷新重试
| @@ -0,0 +1 @@ | |||
| 1 | + | ||
Rsrc/manager/sdk/tests/resources/examples/simple_agent/openjiuwen_agent-1.0.0-py3-none-any.whl→management/tests/resources/examples/simple_agent/openjiuwen_agent-1.0.0-py3-none-any.whl+0-0
文件重命名但无更改。
Rsrc/manager/sdk/tests/resources/examples/simple_agent/pyproject.toml→management/tests/resources/examples/simple_agent/pyproject.toml+0-0
文件重命名但无更改。
Rsrc/manager/examples/requirements.txt→management/tests/resources/examples/simple_agent/requirements.txt+0-0
文件重命名但无更改。
Rsrc/manager/sdk/tests/resources/examples/simple_agent/simple_agent/__init__.py→management/tests/resources/examples/simple_agent/simple_agent/__init__.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/tests/resources/examples/simple_agent/simple_agent/__main__.py→management/tests/resources/examples/simple_agent/simple_agent/__main__.py+0-0
文件重命名但无更改。
Rsrc/manager/sdk/tests/resources/examples/simple_agent/requirements.txt→management/tests/resources/examples/simple_plugin/requirements.txt+0-0
文件重命名但无更改。
Rsrc/manager/examples/simple_plugin.py→management/tests/resources/examples/simple_plugin/simple_plugin.py+0-0
文件重命名但无更改。
Rsrc/manager/server/src/converter/__init__.py→server/openjiuwen_runtime/server/converter/__init__.py+0-0
文件重命名但无更改。
Rsrc/manager/server/src/converter/agent_converter.py→server/openjiuwen_runtime/server/converter/agent_converter.py+0-0
文件重命名但无更改。
Rsrc/manager/server/src/middleware/tenant.py→server/openjiuwen_runtime/server/middleware/tenant.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/manager/server/src/models/__init__.py→server/openjiuwen_runtime/server/models/__init__.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/manager/server/src/models/request.py→server/openjiuwen_runtime/server/models/request.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/manager/server/src/oss/__init__.py→server/openjiuwen_runtime/server/oss/__init__.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/manager/server/src/oss/client.py→server/openjiuwen_runtime/server/oss/client.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/sdk/src/core/agent_app.py→service/openjiuwen_runtime/service/core/agent_app.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/sdk/src/core/app_group.py→service/openjiuwen_runtime/service/core/app_group.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/sdk/src/core/base_app.py→service/openjiuwen_runtime/service/core/base_app.py+0-0文件内容审核中,请稍后刷新重试
Rsrc/sdk/src/core/plugin_app.py→service/openjiuwen_runtime/service/core/plugin_app.py+0-0文件内容审核中,请稍后刷新重试
| @@ -3,7 +3,7 @@ requires = ["setuptools>=61.0", "wheel"] | |||
| 3 | build-backend = "setuptools.build_meta" | 3 | build-backend = "setuptools.build_meta" |
| 4 | 4 | ||
| 5 | [project] | 5 | [project] |
| 6 | -name = "openjiuwen-runtime-sdk" | 6 | +name = "openjiuwen-runtime-service" |
| 7 | version = "0.1.0" | 7 | version = "0.1.0" |
| 8 | description = "OpenJiuwen Runtime" | 8 | description = "OpenJiuwen Runtime" |
| 9 | requires-python = ">=3.11.4" | 9 | requires-python = ">=3.11.4" |
| @@ -29,14 +29,8 @@ dev = [ | |||
| 29 | [[tool.uv.index]] | 29 | [[tool.uv.index]] |
| 30 | url = "https://mirrors.aliyun.com/pypi/simple/" | 30 | url = "https://mirrors.aliyun.com/pypi/simple/" |
| 31 | 31 | ||
| 32 | -[tool.setuptools] | 32 | +[tool.setuptools.packages.find] |
| 33 | -packages = [ | 33 | +where = ["."] |
| 34 | - "openjiuwen_runtime.sdk", | 34 | +exclude = ["*.egg-info", "tests"] |
| 35 | - "openjiuwen_runtime.sdk.core", | 35 | +include = ["openjiuwen_runtime*"] |
| 36 | - "openjiuwen_runtime.sdk.models", | ||
| 37 | -] | ||
| 38 | 36 | ||
| 39 | -[tool.setuptools.package-dir] | ||
| 40 | -"openjiuwen_runtime.sdk" = "src" | ||
| 41 | -"openjiuwen_runtime.sdk.core" = "src/core" | ||
| 42 | -"openjiuwen_runtime.sdk.models" = "src/models" | ||
| @@ -1,59 +0,0 @@ | |||
| 1 | -# Python | ||
| 2 | -__pycache__/ | ||
| 3 | -*.py[cod] | ||
| 4 | -*$py.class | ||
| 5 | -*.so | ||
| 6 | -.Python | ||
| 7 | -build/ | ||
| 8 | -develop-eggs/ | ||
| 9 | -dist/ | ||
| 10 | -downloads/ | ||
| 11 | -eggs/ | ||
| 12 | -.eggs/ | ||
| 13 | -lib/ | ||
| 14 | -lib64/ | ||
| 15 | -parts/ | ||
| 16 | -sdist/ | ||
| 17 | -var/ | ||
| 18 | -wheels/ | ||
| 19 | -*.egg-info/ | ||
| 20 | -.installed.cfg | ||
| 21 | -*.egg | ||
| 22 | - | ||
| 23 | -# Virtual environments | ||
| 24 | -.venv/ | ||
| 25 | -venv/ | ||
| 26 | -ENV/ | ||
| 27 | -env/ | ||
| 28 | - | ||
| 29 | -# IDE | ||
| 30 | -.vscode/ | ||
| 31 | -.idea/ | ||
| 32 | -*.swp | ||
| 33 | -*.swo | ||
| 34 | -*~ | ||
| 35 | - | ||
| 36 | -# Testing | ||
| 37 | -.pytest_cache/ | ||
| 38 | -.coverage | ||
| 39 | -htmlcov/ | ||
| 40 | -.tox/ | ||
| 41 | - | ||
| 42 | -# Environment | ||
| 43 | -.env | ||
| 44 | -.env.local | ||
| 45 | - | ||
| 46 | -# Database | ||
| 47 | -*.db | ||
| 48 | -*.sqlite | ||
| 49 | -*.sqlite3 | ||
| 50 | - | ||
| 51 | -# Logs | ||
| 52 | -*.log | ||
| 53 | - | ||
| 54 | -# OS | ||
| 55 | -.DS_Store | ||
| 56 | -Thumbs.db | ||
| 57 | - | ||
| 58 | -# Claude | ||
| 59 | -.claude/ | ||
| @@ -1,294 +0,0 @@ | |||
| 1 | -# Agent Runtime Manager | ||
| 2 | - | ||
| 3 | -**openjiuwen-runtime** 的部署管理系统,提供 Agent 和 Plugin 的部署、查询和管理功能。 | ||
| 4 | - | ||
| 5 | -## 核心特性 | ||
| 6 | - | ||
| 7 | -### 虚拟环境隔离 | ||
| 8 | -- 每个部署使用独立的虚拟环境,避免依赖冲突 | ||
| 9 | -- 删除部署时自动清理虚拟环境 | ||
| 10 | -- 支持跨平台(Windows/Linux/Mac) | ||
| 11 | - | ||
| 12 | -### WHL 包部署 | ||
| 13 | -- 标准化的 Python 包分发格式 | ||
| 14 | -- 自动解析包名,无需手动指定 | ||
| 15 | -- 自动安装 WHL 包依赖到独立虚拟环境 | ||
| 16 | - | ||
| 17 | -### 灵活的管理方式 | ||
| 18 | -- **CLI 模式**: 命令行工具,适合本地开发测试 | ||
| 19 | -- **SDK 模式**: Python SDK,适合集成到其他系统 | ||
| 20 | -- **Server 模式**: REST API(预留,供 AgentStudio 调用) | ||
| 21 | - | ||
| 22 | -## 快速开始 | ||
| 23 | - | ||
| 24 | -### 1. 安装 CLI | ||
| 25 | - | ||
| 26 | -```bash | ||
| 27 | -# 进入 CLI 目录 | ||
| 28 | -cd cli | ||
| 29 | - | ||
| 30 | -# 创建虚拟环境并安装依赖 | ||
| 31 | -uv venv | ||
| 32 | -uv sync | ||
| 33 | - | ||
| 34 | -# 安装 CLI(editable 模式) | ||
| 35 | -uv pip install -e ./ | ||
| 36 | -``` | ||
| 37 | - | ||
| 38 | -### 2. 准备 WHL 包 | ||
| 39 | - | ||
| 40 | -```bash | ||
| 41 | -# 构建示例 Agent WHL 包 | ||
| 42 | -cd examples/my_agent | ||
| 43 | -py -m build --outdir ../../dist | ||
| 44 | -``` | ||
| 45 | - | ||
| 46 | -### 3. 部署 Agent | ||
| 47 | - | ||
| 48 | -```bash | ||
| 49 | -# 部署(包名自动从 WHL 解析) | ||
| 50 | -agent-runtime-manager agent deploy "E:/code/agent-runtime/src/manager/examples/dist/my_agent-1.0.0-py3-none-any.whl" | ||
| 51 | - | ||
| 52 | -# 查看部署列表 | ||
| 53 | -agent-runtime-manager agent list | ||
| 54 | - | ||
| 55 | -# 查看部署详情 | ||
| 56 | -agent-runtime-manager agent get <deployment_id> | ||
| 57 | - | ||
| 58 | -# 删除部署 | ||
| 59 | -agent-runtime-manager agent delete <deployment_id> | ||
| 60 | -``` | ||
| 61 | - | ||
| 62 | -## CLI 使用 | ||
| 63 | - | ||
| 64 | -### Agent 命令 | ||
| 65 | - | ||
| 66 | -```bash | ||
| 67 | -# 部署 Agent(自动解析包名) | ||
| 68 | -agent-runtime-manager agent deploy <whl_path> [--port PORT] | ||
| 69 | - | ||
| 70 | -# 查询列表 | ||
| 71 | -agent-runtime-manager agent list [--status STATUS] | ||
| 72 | - | ||
| 73 | -# 获取详情 | ||
| 74 | -agent-runtime-manager agent get <deployment_id> | ||
| 75 | - | ||
| 76 | -# 删除部署 | ||
| 77 | -agent-runtime-manager agent delete <deployment_id> | ||
| 78 | -``` | ||
| 79 | - | ||
| 80 | -### Plugin 命令 | ||
| 81 | - | ||
| 82 | -```bash | ||
| 83 | -# 部署 Plugin | ||
| 84 | -agent-runtime-manager plugin deploy <whl_path> [--port PORT] | ||
| 85 | - | ||
| 86 | -# 查询列表 | ||
| 87 | -agent-runtime-manager plugin list [--status STATUS] | ||
| 88 | - | ||
| 89 | -# 获取详情 | ||
| 90 | -agent-runtime-manager plugin get <deployment_id> | ||
| 91 | - | ||
| 92 | -# 删除部署 | ||
| 93 | -agent-runtime-manager plugin delete <deployment_id> | ||
| 94 | -``` | ||
| 95 | - | ||
| 96 | -## SDK 使用 | ||
| 97 | - | ||
| 98 | -```python | ||
| 99 | -from openjiuwen_runtime.management.sdk import DeploymentManager | ||
| 100 | - | ||
| 101 | -manager = DeploymentManager() | ||
| 102 | - | ||
| 103 | -# 部署 Agent(包名自动解析) | ||
| 104 | -result = await manager.deploy_agent( | ||
| 105 | - whl_path="./my_agent-1.0.0-py3-none-any.whl", | ||
| 106 | - port=8090 | ||
| 107 | -) | ||
| 108 | - | ||
| 109 | -# 查询列表 | ||
| 110 | -deployments = await manager.list_deployments( | ||
| 111 | - deployment_type=DeploymentType.AGENT, | ||
| 112 | - status=DeploymentStatus.RUNNING | ||
| 113 | -) | ||
| 114 | - | ||
| 115 | -# 获取详情 | ||
| 116 | -deployment = await manager.get_deployment(deployment_id) | ||
| 117 | - | ||
| 118 | -# 删除部署 | ||
| 119 | -await manager.delete_deployment(deployment_id) | ||
| 120 | -``` | ||
| 121 | - | ||
| 122 | -## WHL 包规范 | ||
| 123 | - | ||
| 124 | -### 命名规范 | ||
| 125 | - | ||
| 126 | -``` | ||
| 127 | -{package_name}-{version}-{python_tag}-{abi_tag}-{platform_tag}.whl | ||
| 128 | - | ||
| 129 | -示例: | ||
| 130 | -my_agent-1.0.0-py3-none-any.whl | ||
| 131 | -weather_plugin-2.1.0-py3-none-any.whl | ||
| 132 | -``` | ||
| 133 | - | ||
| 134 | -### 目录结构 | ||
| 135 | - | ||
| 136 | -``` | ||
| 137 | -my_agent/ | ||
| 138 | -├── my_agent/ # ✅ 包子目录(必须) | ||
| 139 | -│ ├── __init__.py | ||
| 140 | -│ └── __main__.py # ✅ 主入口文件(必须) | ||
| 141 | -└── setup.py # ✅ 打包配置(必须) | ||
| 142 | -``` | ||
| 143 | - | ||
| 144 | -### __main__.py 要求 | ||
| 145 | - | ||
| 146 | -```python | ||
| 147 | -import argparse | ||
| 148 | - | ||
| 149 | -def main(): | ||
| 150 | - # 1. 必须解析 --host 和 --port 参数 | ||
| 151 | - parser = argparse.ArgumentParser() | ||
| 152 | - parser.add_argument("--host", default="127.0.0.1") | ||
| 153 | - parser.add_argument("--port", type=int, default=8090) | ||
| 154 | - args = parser.parse_args() | ||
| 155 | - | ||
| 156 | - # 2. 必须实现长期运行的服务 | ||
| 157 | - # 例如:FastAPI、Flask 等 HTTP 服务器 | ||
| 158 | - run_server(host=args.host, port=args.port) | ||
| 159 | - | ||
| 160 | -if __name__ == "__main__": | ||
| 161 | - main() | ||
| 162 | -``` | ||
| 163 | - | ||
| 164 | -### setup.py 示例 | ||
| 165 | - | ||
| 166 | -```python | ||
| 167 | -from setuptools import setup, find_packages | ||
| 168 | - | ||
| 169 | -setup( | ||
| 170 | - name="my_agent", | ||
| 171 | - version="1.0.0", | ||
| 172 | - packages=find_packages(), | ||
| 173 | - install_requires=[ | ||
| 174 | - "fastapi>=0.100.0", | ||
| 175 | - "uvicorn>=0.23.0", | ||
| 176 | - ], | ||
| 177 | - python_requires=">=3.8", | ||
| 178 | -) | ||
| 179 | -``` | ||
| 180 | - | ||
| 181 | -## 虚拟环境管理 | ||
| 182 | - | ||
| 183 | -### 目录结构 | ||
| 184 | - | ||
| 185 | -``` | ||
| 186 | -venvs/ | ||
| 187 | -├── agent_20250129_abc123/ # Agent 部署虚拟环境 | ||
| 188 | -│ ├── Scripts/python.exe # Windows | ||
| 189 | -│ ├── Lib/site-packages/ # 已安装的包 | ||
| 190 | -│ └── pyvenv.cfg | ||
| 191 | -└── plugin_20250129_def456/ # Plugin 部署虚拟环境 | ||
| 192 | - ├── bin/python # Linux/Mac | ||
| 193 | - └── ... | ||
| 194 | -``` | ||
| 195 | - | ||
| 196 | -### 自动清理 | ||
| 197 | - | ||
| 198 | -- 部署成功后,虚拟环境会保留直到部署被删除 | ||
| 199 | -- 部署失败时,虚拟环境会自动清理 | ||
| 200 | -- 删除部署时,虚拟环境会自动清理 | ||
| 201 | - | ||
| 202 | -## 配置选项 | ||
| 203 | - | ||
| 204 | -### 环境变量 (.env) | ||
| 205 | - | ||
| 206 | -```bash | ||
| 207 | -# MySQL 数据库 | ||
| 208 | -DB_HOST=124.71.229.79 | ||
| 209 | -DB_PORT=33306 | ||
| 210 | -DB_USER=root | ||
| 211 | -DB_PASSWORD=root | ||
| 212 | -DB_NAME=jiuwen_runtime | ||
| 213 | - | ||
| 214 | -# 虚拟环境 | ||
| 215 | -V_ENVS_ROOT=./venvs # 虚拟环境根目录(默认: ./venvs) | ||
| 216 | -``` | ||
| 217 | - | ||
| 218 | -## 项目架构 | ||
| 219 | - | ||
| 220 | -``` | ||
| 221 | -Agent Runtime Manager | ||
| 222 | -├── sdk/ # Manager SDK(核心共享组件) | ||
| 223 | -│ ├── manager.py # DeploymentManager - 部署管理核心 | ||
| 224 | -│ ├── deployer/ # LocalSubprocessDeployer - WHL 包部署器 | ||
| 225 | -│ ├── database/ # MySQLDatabase - 数据持久化 | ||
| 226 | -│ ├── models/ # Deployment/DeploymentDB - 数据模型 | ||
| 227 | -│ └── utils/ # 工具类 | ||
| 228 | -│ ├── venv_manager.py # 虚拟环境管理 | ||
| 229 | -│ ├── whl_parser.py # WHL 包名解析 | ||
| 230 | -│ ├── port_manager.py # 端口分配 | ||
| 231 | -│ └── id_generator.py # ID 生成 | ||
| 232 | -├── cli/ # CLI 命令行工具 | ||
| 233 | -│ └── src/main.py # Click 命令(agent/plugin deploy/list/get/delete) | ||
| 234 | -└── server/ # REST API Server(预留) | ||
| 235 | -``` | ||
| 236 | - | ||
| 237 | -## 开发指南 | ||
| 238 | - | ||
| 239 | -### 构建示例包 | ||
| 240 | - | ||
| 241 | -```bash | ||
| 242 | -cd examples/my_agent | ||
| 243 | -py -m build --outdir ../../dist | ||
| 244 | -``` | ||
| 245 | - | ||
| 246 | -### 运行测试 | ||
| 247 | - | ||
| 248 | -```bash | ||
| 249 | -cd cli | ||
| 250 | -agent-runtime-manager agent deploy "../examples/dist/my_agent-1.0.0-py3-none-any.whl" | ||
| 251 | -``` | ||
| 252 | - | ||
| 253 | -## 常见问题 | ||
| 254 | - | ||
| 255 | -### 1. Editable 安装问题 | ||
| 256 | - | ||
| 257 | -**症状**: 修改代码后仍然使用旧版本 | ||
| 258 | - | ||
| 259 | -**解决**: | ||
| 260 | -```bash | ||
| 261 | -cd cli | ||
| 262 | -rm -rf .venv/Lib/site-packages/openjiuwen_runtime | ||
| 263 | -uv pip install -e ../sdk | ||
| 264 | -``` | ||
| 265 | - | ||
| 266 | -### 2. WHL 包结构错误 | ||
| 267 | - | ||
| 268 | -**症状**: `No module named xxx` | ||
| 269 | - | ||
| 270 | -**解决**: 确保 WHL 包内有正确的包子目录结构 | ||
| 271 | - | ||
| 272 | -```bash | ||
| 273 | -# 验证 WHL 包内容 | ||
| 274 | -python -m zipfile -l my_agent-1.0.0-py3-none-any.whl | ||
| 275 | -``` | ||
| 276 | - | ||
| 277 | -### 3. 进程立即退出 | ||
| 278 | - | ||
| 279 | -**症状**: 部署后进程很快退出 | ||
| 280 | - | ||
| 281 | -**解决**: `__main__.py` 必须实现长期运行的服务(如 HTTP 服务器) | ||
| 282 | - | ||
| 283 | -## 依赖项 | ||
| 284 | - | ||
| 285 | -### SDK 依赖 | ||
| 286 | -- `sqlalchemy>=2.0.0` - ORM 框架 | ||
| 287 | -- `pymysql>=1.0.0` - MySQL 驱动 | ||
| 288 | -- `pydantic>=2.0.0` - 数据验证 | ||
| 289 | -- `cryptography>=42.0.0` - 加密工具 | ||
| 290 | - | ||
| 291 | -### CLI 依赖 | ||
| 292 | -- `click>=8.0.0` - CLI 框架 | ||
| 293 | -- `python-dotenv>=1.0.0` - 环境变量 | ||
| 294 | -- `fastapi>=0.100.0` - Web 框架(Server 预留) | ||
| @@ -1,49 +0,0 @@ | |||
| 1 | -"""Simple FastAPI Agent Example | ||
| 2 | - | ||
| 3 | -A standalone Python file that can be deployed directly. | ||
| 4 | -""" | ||
| 5 | - | ||
| 6 | -import argparse | ||
| 7 | -import uvicorn | ||
| 8 | -from fastapi import FastAPI | ||
| 9 | -from fastapi.responses import JSONResponse | ||
| 10 | - | ||
| 11 | -# Create FastAPI app | ||
| 12 | -app = FastAPI(title="Simple Agent", version="1.0.0") | ||
| 13 | - | ||
| 14 | - | ||
| 15 | - | ||
| 16 | -async def root(): | ||
| 17 | - """Root endpoint""" | ||
| 18 | - return JSONResponse({ | ||
| 19 | - "message": "Hello World from simple_agent!", | ||
| 20 | - "status": "running" | ||
| 21 | - }) | ||
| 22 | - | ||
| 23 | - | ||
| 24 | - | ||
| 25 | -async def health(): | ||
| 26 | - """Health check""" | ||
| 27 | - return JSONResponse({ | ||
| 28 | - "status": "healthy" | ||
| 29 | - }) | ||
| 30 | - | ||
| 31 | - | ||
| 32 | -def main(): | ||
| 33 | - """Main entry point""" | ||
| 34 | - parser = argparse.ArgumentParser(description="Simple FastAPI Agent") | ||
| 35 | - parser.add_argument("--host", default="127.0.0.1", help="Host to bind to") | ||
| 36 | - parser.add_argument("--port", type=int, default=8090, help="Port to bind to") | ||
| 37 | - args = parser.parse_args() | ||
| 38 | - | ||
| 39 | - # Start uvicorn server | ||
| 40 | - uvicorn.run( | ||
| 41 | - app, | ||
| 42 | - host=args.host, | ||
| 43 | - port=args.port, | ||
| 44 | - log_level="info" | ||
| 45 | - ) | ||
| 46 | - | ||
| 47 | - | ||
| 48 | -if __name__ == "__main__": | ||
| 49 | - main() | ||
| @@ -1,35 +0,0 @@ | |||
| 1 | -"""Mock Agent for testing""" | ||
| 2 | - | ||
| 3 | -import asyncio | ||
| 4 | -from fastapi import FastAPI | ||
| 5 | -from uvicorn import Config, Server | ||
| 6 | - | ||
| 7 | - | ||
| 8 | -app = FastAPI(title="TestAgent") | ||
| 9 | - | ||
| 10 | - | ||
| 11 | - | ||
| 12 | -async def root(): | ||
| 13 | - return {"message": "Hello World"} | ||
| 14 | - | ||
| 15 | - | ||
| 16 | - | ||
| 17 | -async def health(): | ||
| 18 | - return {"status": "healthy"} | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -if __name__ == "__main__": | ||
| 22 | - import argparse | ||
| 23 | - import sys | ||
| 24 | - | ||
| 25 | - parser = argparse.ArgumentParser() | ||
| 26 | - parser.add_argument("--host", default="127.0.0.1") | ||
| 27 | - parser.add_argument("--port", type=int, default=8090) | ||
| 28 | - args = parser.parse_args() | ||
| 29 | - | ||
| 30 | - # 使用 uvicorn 运行 | ||
| 31 | - config = Config(app=app, host=args.host, port=args.port, log_level="info") | ||
| 32 | - server = Server(config) | ||
| 33 | - | ||
| 34 | - print(f"Starting TestAgent on http://{args.host}:{args.port}") | ||
| 35 | - asyncio.run(server.serve()) | ||
| @@ -1,54 +0,0 @@ | |||
| 1 | -"""SDK使用示例 | ||
| 2 | - | ||
| 3 | -使用前请先初始化数据库: | ||
| 4 | - from openjiuwen_runtime.management.sdk import init_database | ||
| 5 | - init_database() | ||
| 6 | -""" | ||
| 7 | - | ||
| 8 | -import asyncio | ||
| 9 | -from pathlib import Path | ||
| 10 | -from dotenv import load_dotenv | ||
| 11 | - | ||
| 12 | -from openjiuwen_runtime.management.sdk import DeploymentManager | ||
| 13 | - | ||
| 14 | -# 加载.env配置文件(manager根目录) | ||
| 15 | -_manager_root = Path(__file__).parent.parent | ||
| 16 | -_env_file = _manager_root / ".env" | ||
| 17 | -load_dotenv(_env_file) | ||
| 18 | - | ||
| 19 | - | ||
| 20 | -async def main(): | ||
| 21 | - """SDK使用示例""" | ||
| 22 | - | ||
| 23 | - # 创建部署管理器 | ||
| 24 | - manager = DeploymentManager() | ||
| 25 | - | ||
| 26 | - # 部署Agent | ||
| 27 | - print("Deploying agent...") | ||
| 28 | - result = await manager.deploy_agent( | ||
| 29 | - local_file_path=str(Path(__file__).parent / "mock_agent_app.py"), | ||
| 30 | - name="HelloAgent", | ||
| 31 | - port=9999, | ||
| 32 | - ) | ||
| 33 | - print(f" Deployment ID: {result['deployment_id']}") | ||
| 34 | - print(f" URL: {result['url']}") | ||
| 35 | - print(f" Status: {result['status']}") | ||
| 36 | - | ||
| 37 | - # 查询部署列表 | ||
| 38 | - print("\nListing agents...") | ||
| 39 | - deployments = await manager.list_deployments() | ||
| 40 | - for dep in deployments: | ||
| 41 | - print(f" - {dep['deployment_id']}: {dep['status']}") | ||
| 42 | - | ||
| 43 | - # 获取部署详情 | ||
| 44 | - deployment = await manager.get_deployment(result['deployment_id']) | ||
| 45 | - print(f"\nDeployment details: {deployment['status']}") | ||
| 46 | - | ||
| 47 | - # 删除部署 | ||
| 48 | - print("\nDeleting deployment...") | ||
| 49 | - await manager.delete_deployment(result['deployment_id']) | ||
| 50 | - print(" Deleted!") | ||
| 51 | - | ||
| 52 | - | ||
| 53 | -if __name__ == "__main__": | ||
| 54 | - asyncio.run(main()) | ||
| @@ -1,2 +0,0 @@ | |||
| 1 | -fastapi>=0.100.0 | ||
| 2 | -uvicorn>=0.23.0 | ||
| @@ -1,62 +0,0 @@ | |||
| 1 | -"""Simple FastAPI Plugin Example | ||
| 2 | - | ||
| 3 | -A standalone Python file that can be deployed directly as a plugin. | ||
| 4 | -""" | ||
| 5 | - | ||
| 6 | -import argparse | ||
| 7 | -import uvicorn | ||
| 8 | -from fastapi import FastAPI | ||
| 9 | -from fastapi.responses import JSONResponse | ||
| 10 | - | ||
| 11 | -# Create FastAPI app | ||
| 12 | -app = FastAPI(title="Simple Plugin", version="1.0.0") | ||
| 13 | - | ||
| 14 | - | ||
| 15 | - | ||
| 16 | -async def root(): | ||
| 17 | - """Root endpoint""" | ||
| 18 | - return JSONResponse({ | ||
| 19 | - "message": "Hello World from simple_plugin!", | ||
| 20 | - "type": "plugin", | ||
| 21 | - "status": "running" | ||
| 22 | - }) | ||
| 23 | - | ||
| 24 | - | ||
| 25 | - | ||
| 26 | -async def list_tools(): | ||
| 27 | - """List available tools""" | ||
| 28 | - return JSONResponse({ | ||
| 29 | - "tools": [ | ||
| 30 | - {"name": "current_weather", "description": "Query current weather"}, | ||
| 31 | - {"name": "weather_forecast", "description": "Query weather forecast"} | ||
| 32 | - ] | ||
| 33 | - }) | ||
| 34 | - | ||
| 35 | - | ||
| 36 | - | ||
| 37 | -async def call_tool(tool_name: str): | ||
| 38 | - """Call a tool""" | ||
| 39 | - return JSONResponse({ | ||
| 40 | - "tool": tool_name, | ||
| 41 | - "result": f"Executed {tool_name} successfully" | ||
| 42 | - }) | ||
| 43 | - | ||
| 44 | - | ||
| 45 | -def main(): | ||
| 46 | - """Main entry point""" | ||
| 47 | - parser = argparse.ArgumentParser(description="Simple FastAPI Plugin") | ||
| 48 | - parser.add_argument("--host", default="127.0.0.1", help="Host to bind to") | ||
| 49 | - parser.add_argument("--port", type=int, default=8091, help="Port to bind to") | ||
| 50 | - args = parser.parse_args() | ||
| 51 | - | ||
| 52 | - # Start uvicorn server | ||
| 53 | - uvicorn.run( | ||
| 54 | - app, | ||
| 55 | - host=args.host, | ||
| 56 | - port=args.port, | ||
| 57 | - log_level="info" | ||
| 58 | - ) | ||
| 59 | - | ||
| 60 | - | ||
| 61 | -if __name__ == "__main__": | ||
| 62 | - main() | ||
| @@ -1,130 +0,0 @@ | |||
| 1 | -"""部署管理器测试""" | ||
| 2 | - | ||
| 3 | -import asyncio | ||
| 4 | -import os | ||
| 5 | -import tempfile | ||
| 6 | -import unittest | ||
| 7 | -from pathlib import Path | ||
| 8 | - | ||
| 9 | -from openjiuwen_runtime.management.sdk import DeploymentManager, DeployMode | ||
| 10 | -from openjiuwen_runtime.management.sdk.db.sqlite_handler import SQLiteHandler | ||
| 11 | -from openjiuwen_runtime.management.sdk.foundation.packaging import package_python_to_whl | ||
| 12 | - | ||
| 13 | - | ||
| 14 | -class ManagerTest(unittest.IsolatedAsyncioTestCase): | ||
| 15 | - """部署管理器测试""" | ||
| 16 | - | ||
| 17 | - async def asyncSetUp(self): | ||
| 18 | - self.temp_dir = tempfile.mkdtemp(prefix="deployment_test_") | ||
| 19 | - self.db_path = os.path.join(self.temp_dir, "test.db") | ||
| 20 | - self.venv_base_path = os.path.join(self.temp_dir, "venvs") | ||
| 21 | - | ||
| 22 | - self.db_handler = SQLiteHandler(self.db_path) | ||
| 23 | - self.manager = DeploymentManager( | ||
| 24 | - db_handler=self.db_handler, | ||
| 25 | - ) | ||
| 26 | - await self.manager.initialize() | ||
| 27 | - | ||
| 28 | - async def asyncTearDown(self): | ||
| 29 | - await self.manager.shutdown() | ||
| 30 | - | ||
| 31 | - import shutil | ||
| 32 | - if os.path.exists(self.temp_dir): | ||
| 33 | - shutil.rmtree(self.temp_dir, ignore_errors=True) | ||
| 34 | - | ||
| 35 | - | ||
| 36 | - async def test_deploy_simple_agent(self): | ||
| 37 | - """测试部署 simple_agent""" | ||
| 38 | - project_root = Path(__file__).parent.parent | ||
| 39 | - simple_agent_dir = project_root / "resources" / "examples" / "simple_agent" | ||
| 40 | - | ||
| 41 | - self.assertTrue(simple_agent_dir.exists(), f"simple_agent directory not found: {simple_agent_dir}") | ||
| 42 | - | ||
| 43 | - with tempfile.TemporaryDirectory(prefix="whl_build_") as build_dir: | ||
| 44 | - whl_path = await package_python_to_whl( | ||
| 45 | - source_dir=str(simple_agent_dir), | ||
| 46 | - output_dir=build_dir, | ||
| 47 | - package_name="simple_agent", | ||
| 48 | - ) | ||
| 49 | - | ||
| 50 | - self.assertTrue(os.path.exists(whl_path), f"WHL file not found: {whl_path}") | ||
| 51 | - | ||
| 52 | - deployment_info = await self.manager.deploy_agent( | ||
| 53 | - name="test_simple_agent", | ||
| 54 | - version="1.0.0", | ||
| 55 | - mode=DeployMode.SUBPROCESS, | ||
| 56 | - package_name="simple_agent", | ||
| 57 | - whl_path=whl_path, | ||
| 58 | - ) | ||
| 59 | - | ||
| 60 | - self.assertIsNotNone(deployment_info) | ||
| 61 | - self.assertEqual(deployment_info.name, "test_simple_agent") | ||
| 62 | - self.assertIsNotNone(deployment_info.url) | ||
| 63 | - | ||
| 64 | - import aiohttp | ||
| 65 | - await asyncio.sleep(3) | ||
| 66 | - | ||
| 67 | - async with aiohttp.ClientSession() as session: | ||
| 68 | - async with session.get(f"{deployment_info.url}/health", timeout=aiohttp.ClientTimeout(total=5)) as resp: | ||
| 69 | - self.assertEqual(resp.status, 200) | ||
| 70 | - data = await resp.json() | ||
| 71 | - self.assertEqual(data.get("status"), "healthy") | ||
| 72 | - | ||
| 73 | - process_info = await self.manager.get_process_info(deployment_info.deployment_id) | ||
| 74 | - self.assertIsNotNone(process_info) | ||
| 75 | - self.assertIsNotNone(process_info.pid) | ||
| 76 | - | ||
| 77 | - success = await self.manager.stop_deployment(deployment_info.deployment_id) | ||
| 78 | - self.assertTrue(success) | ||
| 79 | - | ||
| 80 | - status = await self.manager.get_deployment_status(deployment_info.deployment_id) | ||
| 81 | - from openjiuwen_runtime.management.sdk.models.enums import DeploymentStatus | ||
| 82 | - self.assertEqual(status, DeploymentStatus.STOPPED) | ||
| 83 | - | ||
| 84 | - | ||
| 85 | - async def test_deploy_simple_agent_whl(self): | ||
| 86 | - """测试部署 simple_agent""" | ||
| 87 | - with tempfile.TemporaryDirectory(prefix="whl_build_") as build_dir: | ||
| 88 | - project_root = Path(__file__).parent.parent | ||
| 89 | - whl_path = str( | ||
| 90 | - project_root / "resources" / "examples" / "simple_agent" / "openjiuwen_agent-1.0.0-py3-none-any.whl") | ||
| 91 | - | ||
| 92 | - deployment_info = await self.manager.deploy_agent( | ||
| 93 | - name="test_simple_agent", | ||
| 94 | - version="1.0.0", | ||
| 95 | - mode=DeployMode.SUBPROCESS, | ||
| 96 | - package_name="simple_agent", | ||
| 97 | - whl_path=whl_path, | ||
| 98 | - ) | ||
| 99 | - | ||
| 100 | - self.assertIsNotNone(deployment_info) | ||
| 101 | - self.assertEqual(deployment_info.name, "test_simple_agent") | ||
| 102 | - self.assertIsNotNone(deployment_info.url) | ||
| 103 | - | ||
| 104 | - import aiohttp | ||
| 105 | - await asyncio.sleep(3) | ||
| 106 | - | ||
| 107 | - async with aiohttp.ClientSession() as session: | ||
| 108 | - async with session.get(f"{deployment_info.url}/health", timeout=aiohttp.ClientTimeout(total=5)) as resp: | ||
| 109 | - self.assertEqual(resp.status, 200) | ||
| 110 | - data = await resp.json() | ||
| 111 | - self.assertEqual(data.get("status"), "healthy") | ||
| 112 | - | ||
| 113 | - process_info = await self.manager.get_process_info(deployment_info.deployment_id) | ||
| 114 | - self.assertIsNotNone(process_info) | ||
| 115 | - self.assertIsNotNone(process_info.pid) | ||
| 116 | - | ||
| 117 | - success = await self.manager.stop_deployment(deployment_info.deployment_id) | ||
| 118 | - self.assertTrue(success) | ||
| 119 | - | ||
| 120 | - status = await self.manager.get_deployment_status(deployment_info.deployment_id) | ||
| 121 | - from openjiuwen_runtime.management.sdk.models.enums import DeploymentStatus | ||
| 122 | - self.assertEqual(status, DeploymentStatus.STOPPED) | ||
| 123 | - | ||
| 124 | - | ||
| 125 | -if __name__ == '__main__': | ||
| 126 | - a = ManagerTest() | ||
| 127 | - asyncio.run(a.asyncSetUp()) | ||
| 128 | - result = asyncio.run(a.test_deploy_simple_agent_whl()) | ||
| 129 | - asyncio.run(a.asyncTearDown()) | ||
| 130 | - print(result) | ||
The file is empty