reglow-agent 0.6.1__py3-none-any.whl

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.
Files changed (51) hide show
  1. reglow_agent/__init__.py +64 -0
  2. reglow_agent/agent/__init__.py +28 -0
  3. reglow_agent/agent/cli.py +112 -0
  4. reglow_agent/agent/engine/__init__.py +27 -0
  5. reglow_agent/agent/engine/backend_generator.py +108 -0
  6. reglow_agent/agent/engine/context.py +519 -0
  7. reglow_agent/agent/engine/domain.py +149 -0
  8. reglow_agent/agent/engine/frontend_generator.py +82 -0
  9. reglow_agent/agent/engine/registry.py +49 -0
  10. reglow_agent/agent/engine/requirement_analyzer.py +790 -0
  11. reglow_agent/agent/engine/runner.py +140 -0
  12. reglow_agent/agent/engine/schema_sync.py +143 -0
  13. reglow_agent/eval/__init__.py +15 -0
  14. reglow_agent/eval/cases.py +343 -0
  15. reglow_agent/eval/cli.py +41 -0
  16. reglow_agent/eval/runner.py +168 -0
  17. reglow_agent/gen_templates/__init__.py +1 -0
  18. reglow_agent/gen_templates/backend/__init__.py +0 -0
  19. reglow_agent/gen_templates/backend/migration/version.py.j2 +55 -0
  20. reglow_agent/gen_templates/backend/module/__init__.py +0 -0
  21. reglow_agent/gen_templates/backend/module/__init__.py.j2 +1 -0
  22. reglow_agent/gen_templates/backend/module/controller.py.j2 +140 -0
  23. reglow_agent/gen_templates/backend/module/model.py.j2 +19 -0
  24. reglow_agent/gen_templates/backend/module/repository.py.j2 +146 -0
  25. reglow_agent/gen_templates/backend/module/router.py.j2 +3 -0
  26. reglow_agent/gen_templates/backend/module/schema.py.j2 +83 -0
  27. reglow_agent/gen_templates/backend/module/service.py.j2 +129 -0
  28. reglow_agent/gen_templates/backend/seed/seed.py.j2 +64 -0
  29. reglow_agent/gen_templates/frontend/module/api.ts.j2 +75 -0
  30. reglow_agent/gen_templates/frontend/module/index.vue.j2 +409 -0
  31. reglow_agent/modules/__init__.py +6 -0
  32. reglow_agent/modules/agent_runtime/__init__.py +46 -0
  33. reglow_agent/modules/agent_runtime/audit.py +89 -0
  34. reglow_agent/modules/agent_runtime/controller.py +82 -0
  35. reglow_agent/modules/agent_runtime/executor.py +110 -0
  36. reglow_agent/modules/agent_runtime/model.py +37 -0
  37. reglow_agent/modules/agent_runtime/repository.py +70 -0
  38. reglow_agent/modules/agent_runtime/router.py +3 -0
  39. reglow_agent/modules/agent_runtime/schema.py +54 -0
  40. reglow_agent/modules/agent_runtime/service.py +87 -0
  41. reglow_agent/modules/agent_runtime/tool_registry.py +109 -0
  42. reglow_agent/modules/schema_dsl/__init__.py +44 -0
  43. reglow_agent/modules/schema_dsl/controller.py +41 -0
  44. reglow_agent/modules/schema_dsl/models.py +270 -0
  45. reglow_agent/modules/schema_dsl/parser.py +44 -0
  46. reglow_agent/modules/schema_dsl/router.py +3 -0
  47. reglow_agent/modules/schema_dsl/validator.py +325 -0
  48. reglow_agent-0.6.1.dist-info/METADATA +14 -0
  49. reglow_agent-0.6.1.dist-info/RECORD +51 -0
  50. reglow_agent-0.6.1.dist-info/WHEEL +5 -0
  51. reglow_agent-0.6.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,64 @@
1
+ """reglow-agent —— Reglow AI-Native 生成能力(Python 附加产品包)
2
+
3
+ 不属于 reglow 基础库。基础库只承诺四语言同构的基础模块;
4
+ 本包是 AI-Native 产品的本体(Schema DSL / 生成引擎 / Agent 运行时 / 评测集)。
5
+
6
+ 挂载方式(业务侧显式挂载,基础库不含任何 agent 知识、也不反向依赖本包):
7
+
8
+ import reglow_agent
9
+ from reglow.server import app
10
+
11
+ reglow_agent.register(app) # 挂载 /admin/api/v1/agent/* 与 /schema_dsl/* 等路由
12
+ """
13
+ from __future__ import annotations
14
+
15
+ from typing import TYPE_CHECKING
16
+
17
+ if TYPE_CHECKING:
18
+ from fastapi import FastAPI
19
+
20
+ __version__ = "0.6.0"
21
+
22
+ # 本包提供对外路由的模块包(相对 reglow 默认发现根是额外的根)
23
+ ROUTER_ROOTS: list[str] = ["reglow_agent.modules"]
24
+
25
+ __all__ = ["register", "register_models", "ROUTER_ROOTS", "__version__"]
26
+
27
+
28
+ def register_models() -> None:
29
+ """把本包 ORM 模型注册进 Base.metadata。
30
+
31
+ 基础库的 _import_all_models() 只含基础库表结构,因此调用方必须在
32
+ create_all()(或 _auto_init_database)之前调用本函数,否则本包的表
33
+ (如 sys_agent_audit / sys_agent_tool)不会被创建。
34
+ """
35
+ import reglow_agent.modules.agent_runtime.model # noqa: F401
36
+
37
+
38
+ def register(app: "FastAPI") -> None:
39
+ """把本包的模块路由挂载到给定应用,并注册本包 ORM 模型。
40
+
41
+ 基础库的路由自动发现只扫描 reglow.modules 与 app.modules;本包位于
42
+ reglow_agent.modules,因此需要应用侧显式调用本函数完成挂载。
43
+ 路径与标签约定复用基础库的 tooling,避免两处实现漂移。
44
+ """
45
+ from fastapi import APIRouter
46
+
47
+ from reglow.core.plugin import (
48
+ ADMIN_API_PREFIX,
49
+ CLIENT_API_PREFIX,
50
+ discover_client_routers,
51
+ discover_routers,
52
+ mount_admin_routers,
53
+ mount_client_routers,
54
+ )
55
+
56
+ register_models()
57
+
58
+ admin_api = APIRouter(prefix=ADMIN_API_PREFIX)
59
+ mount_admin_routers(admin_api, discover_routers(ROUTER_ROOTS))
60
+ app.include_router(admin_api)
61
+
62
+ client_api = APIRouter(prefix=CLIENT_API_PREFIX)
63
+ mount_client_routers(client_api, discover_client_routers(ROUTER_ROOTS))
64
+ app.include_router(client_api)
@@ -0,0 +1,28 @@
1
+ """AI-Native:生成引擎内核(agent)
2
+
3
+ 生成引擎 L1 = Schema DSL 输入 + 代码生成器(backend/frontend)+ 生成器注册表。
4
+ 与 agent_runtime(运行时)分离:此处是"开发时生成",agent_runtime 是"运行时执行"。
5
+ """
6
+ from .engine import (
7
+ BackendGenerator,
8
+ FrontendGenerator,
9
+ GenerationResult,
10
+ GeneratorRegistry,
11
+ build_backend_context,
12
+ generate_backend,
13
+ generate_frontend,
14
+ generate_module,
15
+ registry,
16
+ )
17
+
18
+ __all__ = [
19
+ "BackendGenerator",
20
+ "FrontendGenerator",
21
+ "GenerationResult",
22
+ "GeneratorRegistry",
23
+ "build_backend_context",
24
+ "generate_backend",
25
+ "generate_frontend",
26
+ "generate_module",
27
+ "registry",
28
+ ]
@@ -0,0 +1,112 @@
1
+ """生成引擎 CLI(python -m reglow_agent.agent.cli)
2
+
3
+ 用法:
4
+ python -m reglow_agent.agent.cli validate schema.yaml # 校验 Schema
5
+ python -m reglow_agent.agent.cli generate schema.yaml # 生成后端(六层+迁移+种子,默认 ./generated)
6
+ python -m reglow_agent.agent.cli generate schema.yaml -o . # 指定目标后端工程根目录
7
+ python -m reglow_agent.agent.cli generate schema.yaml -f src # 同时生成前端(frontend-admin/src)
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ import sys
13
+ from pathlib import Path
14
+
15
+ from reglow_agent.agent.engine.runner import generate_backend, generate_module
16
+ from reglow_agent.modules.schema_dsl.parser import parse_schema_text
17
+ from reglow_agent.modules.schema_dsl.validator import SchemaValidationError, validate_schema
18
+
19
+
20
+ def _load_schema(path: str):
21
+ return parse_schema_text(Path(path).read_text(encoding="utf-8"))
22
+
23
+
24
+ def cmd_validate(args: argparse.Namespace) -> int:
25
+ data = _load_schema(args.schema_file)
26
+ issues = validate_schema(data)
27
+ if issues:
28
+ print(f"校验失败:{len(issues)} 处错误", file=sys.stderr)
29
+ for issue in issues:
30
+ print(f" [{issue.path}] {issue.message}", file=sys.stderr)
31
+ return 1
32
+ module = data.get("module", "?")
33
+ fields = len(data.get("fields", []))
34
+ print(f"校验通过:module={module},fields={fields}")
35
+ return 0
36
+
37
+
38
+ def cmd_generate(args: argparse.Namespace) -> int:
39
+ data = _load_schema(args.schema_file)
40
+ if args.frontend_src:
41
+ result = generate_module(data, args.target_dir, args.frontend_src)
42
+ print(f"生成完成(前后端):{result.module}({result.total_lines} 行 / {len(result.files)} 个文件)")
43
+ else:
44
+ result = generate_backend(data, args.target_dir)
45
+ print(f"生成完成(后端):{result.module}({result.total_lines} 行 / {len(result.files)} 个文件)")
46
+ print(f"目标目录:{result.target_dir}")
47
+ return 0
48
+
49
+
50
+ def cmd_analyze(args: argparse.Namespace) -> int:
51
+ """L2 需求对话:自然语言需求 → Schema DSL 或澄清问题"""
52
+ import asyncio
53
+
54
+ from reglow.core.database import AsyncSessionLocal
55
+ from reglow_agent.agent.engine.requirement_analyzer import RequirementAnalyzer
56
+
57
+ async def _run() -> dict:
58
+ async with AsyncSessionLocal() as db:
59
+ analyzer = RequirementAnalyzer(db, provider=args.provider, model=args.model)
60
+ return (await analyzer.generate_schema(args.requirement)).to_dict()
61
+
62
+ result = asyncio.run(_run())
63
+ if result["valid"]:
64
+ print(f"Schema 校验通过(provider={result['provider']})")
65
+ print(result["schema_text"])
66
+ return 0
67
+ if result["questions"]:
68
+ print("需要澄清的问题:")
69
+ for i, q in enumerate(result["questions"], 1):
70
+ print(f" {i}. {q}")
71
+ return 1
72
+ print("未能生成 Schema:", file=sys.stderr)
73
+ for issue in result["issues"]:
74
+ print(f" {issue}", file=sys.stderr)
75
+ return 1
76
+
77
+
78
+ def main(argv: list[str] | None = None) -> int:
79
+ parser = argparse.ArgumentParser(prog="reglow-gen", description="Reglow 生成引擎 CLI")
80
+ sub = parser.add_subparsers(dest="command", required=True)
81
+
82
+ p_validate = sub.add_parser("validate", help="校验 Schema 文件")
83
+ p_validate.add_argument("schema_file", help="Schema YAML/JSON 文件路径")
84
+ p_validate.set_defaults(func=cmd_validate)
85
+
86
+ p_generate = sub.add_parser("generate", help="生成代码(后端默认,-f 时前后端一起)")
87
+ p_generate.add_argument("schema_file", help="Schema YAML/JSON 文件路径")
88
+ p_generate.add_argument("-o", "--target-dir", default="./generated", help="目标后端工程根目录(默认 ./generated)")
89
+ p_generate.add_argument("-f", "--frontend-src", default=None, help="目标前端 src 目录(提供则同时生成前端)")
90
+ p_generate.set_defaults(func=cmd_generate)
91
+
92
+ p_analyze = sub.add_parser("analyze", help="L2 需求对话:自然语言 → Schema DSL(或澄清问题)")
93
+ p_analyze.add_argument("requirement", help="自然语言需求描述(引号包裹)")
94
+ p_analyze.add_argument("--provider", default=None, help="LLM 服务商(默认取 ai 模块配置的 deepseek)")
95
+ p_analyze.add_argument("--model", default=None, help="模型名(默认取 provider 配置的 model)")
96
+ p_analyze.set_defaults(func=cmd_analyze)
97
+
98
+ args = parser.parse_args(argv)
99
+ try:
100
+ return args.func(args)
101
+ except SchemaValidationError as exc:
102
+ print(f"Schema 校验失败:{exc}", file=sys.stderr)
103
+ for issue in exc.issues:
104
+ print(f" [{issue.path}] {issue.message}", file=sys.stderr)
105
+ return 1
106
+ except Exception as exc: # noqa: BLE001
107
+ print(f"错误:{exc}", file=sys.stderr)
108
+ return 2
109
+
110
+
111
+ if __name__ == "__main__":
112
+ raise SystemExit(main())
@@ -0,0 +1,27 @@
1
+ """生成引擎 L1 —— 后端六层 + Alembic 迁移 + 菜单/字典种子 + 前端页面生成
2
+
3
+ Schema(ModuleSchema)→ backend(modules/{module}/ + alembic/versions/)→ frontend(views + api)。
4
+ M1 只做后端六层;M2 补齐迁移、种子与前端页面(见《reglow-V1.0版本计划.md》)。
5
+ """
6
+ from .backend_generator import BackendGenerator, build_backend_context, new_revision
7
+ from .frontend_generator import FrontendGenerator
8
+ from .registry import GeneratorRegistry, registry
9
+ from .runner import (
10
+ GenerationResult,
11
+ generate_backend,
12
+ generate_frontend,
13
+ generate_module,
14
+ )
15
+
16
+ __all__ = [
17
+ "BackendGenerator",
18
+ "FrontendGenerator",
19
+ "GenerationResult",
20
+ "GeneratorRegistry",
21
+ "build_backend_context",
22
+ "generate_backend",
23
+ "generate_frontend",
24
+ "generate_module",
25
+ "new_revision",
26
+ "registry",
27
+ ]
@@ -0,0 +1,108 @@
1
+ """后端生成器:Schema → 六层代码 + Alembic 迁移 + 菜单/字典种子"""
2
+ from __future__ import annotations
3
+
4
+ import logging
5
+ from datetime import datetime
6
+ from pathlib import Path
7
+
8
+ from jinja2 import Environment, FileSystemLoader, TemplateNotFound
9
+
10
+ from reglow_agent.modules.schema_dsl.models import ModuleSchema
11
+
12
+ from .context import (
13
+ build_backend_context,
14
+ build_migration_context,
15
+ build_seed_context,
16
+ default_backend_templates_dir,
17
+ )
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+ # 六层文件名(模板 → 产物文件名)
22
+ BACKEND_FILES: dict[str, str] = {
23
+ "__init__.py": "__init__.py",
24
+ "model.py": "model.py",
25
+ "schema.py": "schema.py",
26
+ "repository.py": "repository.py",
27
+ "service.py": "service.py",
28
+ "controller.py": "controller.py",
29
+ "router.py": "router.py",
30
+ }
31
+
32
+
33
+ def new_revision(module: str) -> str:
34
+ """生成 Alembic revision id(时间戳_模块名)"""
35
+ return datetime.now().strftime("%Y%m%d%H%M%S") + f"_{module}"
36
+
37
+
38
+ class BackendGenerator:
39
+ """L1 后端生成器:ModuleSchema → 六层 + 迁移 + 种子"""
40
+
41
+ def __init__(self, templates_dir: Path | None = None):
42
+ self.templates_dir = templates_dir or default_backend_templates_dir()
43
+ if not self.templates_dir.is_dir():
44
+ raise FileNotFoundError(f"生成模板目录不存在: {self.templates_dir}")
45
+ self._env = Environment(
46
+ loader=FileSystemLoader(str(self.templates_dir)),
47
+ keep_trailing_newline=True,
48
+ trim_blocks=True,
49
+ lstrip_blocks=True,
50
+ )
51
+
52
+ def _render(self, template_name: str, **context) -> str:
53
+ try:
54
+ template = self._env.get_template(template_name)
55
+ except TemplateNotFound:
56
+ raise FileNotFoundError(f"模板缺失: {self.templates_dir / template_name}")
57
+ return template.render(**context)
58
+
59
+ def render(self, schema: ModuleSchema) -> dict[str, str]:
60
+ """渲染全部后端文件,返回 {逻辑名: 内容}"""
61
+ context = build_backend_context(schema)
62
+ rendered: dict[str, str] = {}
63
+ for template_name, file_name in BACKEND_FILES.items():
64
+ rendered[f"module/{file_name}"] = self._render(f"module/{template_name}.j2", **context)
65
+ return rendered
66
+
67
+ def render_migration(self, schema: ModuleSchema, revision: str | None = None,
68
+ down_revision: str = "") -> tuple[str, str]:
69
+ """渲染 Alembic 迁移,返回 (revision, 内容)"""
70
+ revision = revision or new_revision(schema.module)
71
+ context = build_migration_context(schema, revision, down_revision)
72
+ return revision, self._render("migration/version.py.j2", **context)
73
+
74
+ def render_seed(self, schema: ModuleSchema) -> str:
75
+ """渲染菜单/字典种子脚本"""
76
+ return self._render("seed/seed.py.j2", **build_seed_context(schema))
77
+
78
+ def generate(self, schema: ModuleSchema, target_dir: Path,
79
+ revision: str | None = None, down_revision: str = "") -> dict[str, Path]:
80
+ """渲染并写入:六层(modules/{module}/)+ 迁移(alembic/versions/)+ 种子(modules/{module}/seed.py)。
81
+
82
+ Returns:
83
+ {逻辑名: 绝对路径}
84
+ """
85
+ module_dir = target_dir / "modules" / schema.module
86
+ module_dir.mkdir(parents=True, exist_ok=True)
87
+ rendered = self.render(schema)
88
+ written: dict[str, Path] = {}
89
+ for logical, content in rendered.items():
90
+ file_path = module_dir / Path(logical).name
91
+ file_path.write_text(content, encoding="utf-8")
92
+ written[logical] = file_path
93
+
94
+ # 种子脚本
95
+ seed_path = module_dir / "seed.py"
96
+ seed_path.write_text(self.render_seed(schema), encoding="utf-8")
97
+ written["module/seed.py"] = seed_path
98
+
99
+ # Alembic 迁移
100
+ revision = revision or new_revision(schema.module)
101
+ versions_dir = target_dir / "alembic" / "versions"
102
+ versions_dir.mkdir(parents=True, exist_ok=True)
103
+ migration_path = versions_dir / f"{revision}.py"
104
+ migration_path.write_text(self.render_migration(schema, revision, down_revision)[1], encoding="utf-8")
105
+ written["migration"] = migration_path
106
+
107
+ logger.info("生成后端模块 %s → %s(%d 个文件 + 迁移)", schema.module, module_dir, len(written))
108
+ return written