@kmlckj/licos-ai-cli 1.4.5 → 1.4.7

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.
@@ -4,7 +4,7 @@ version = "0.1.0"
4
4
  description = "LICOS LangGraph agent project"
5
5
  requires-python = ">=3.12"
6
6
  dependencies = [
7
- "licos-agent-runtime>=0.3.4",
7
+ "licos-agent-runtime>=0.3.6",
8
8
  "licos-dev-sdk>=0.4.9",
9
9
  ]
10
10
 
@@ -1,2 +1,2 @@
1
- licos-agent-runtime>=0.3.4
1
+ licos-agent-runtime>=0.3.6
2
2
  licos-dev-sdk>=0.4.9
@@ -33,4 +33,6 @@
33
33
  - 如果文档与源码 schema 冲突,应修正文档,不要为了匹配文档清空 `GraphInput` / `GraphOutput`。
34
34
  - 可视化条件节点必须在 `graph.py` 的 `add_node(..., metadata={...})` 中保存 `definition.branches`;`branches[].id` 与路由函数返回值一致,`branches[].target` 与 `add_conditional_edges(..., path_map=...)` 目标一致。条件节点函数只透传状态,不要把路由函数同时作为节点函数。
35
35
  - 根据画布 QueryDiff 修改已有 Action 节点时,必须以 QueryDiff 的 `node.id` 为准更新同一个节点的 metadata、状态字段和实现文件;只有 QueryDiff 明确是新增节点且用户明确要增加业务步骤时才新增节点。
36
- - 禁止保留默认标题“请填写动作内容”作为最终节点标题;Action 节点标题必须稳定、可读并表达业务含义,已有节点的 ID 不能因为标题或内容调整而改变。
36
+ - 禁止保留默认标题“请填写动作内容”作为最终节点标题;Action 节点标题必须稳定、可读并表达业务含义,已有节点的 ID 不能因为标题或内容调整而改变。
37
+ - 默认不创建持久化配置、迁移文件或检查点表。只有用户明确要求本项目断点续跑时,才按 README 中的运行时契约在本项目生成版本化 SQL 迁移,核对目标项目与环境并执行、加入 `config/workflow-runtime.json`,并检查图编译时使用 `workflow_checkpointer()`。
38
+ - 有副作用的业务节点在恢复后可能再次执行。写入外部系统必须使用由工作流实例 ID、稳定节点 ID 和业务操作号组成的幂等键;对没有幂等能力的系统,先查询原操作结果,状态不明时停止并交给业务规则处理,不自动重复写入。
@@ -50,6 +50,55 @@ bash scripts/http_run.sh -p <%= port %>
50
50
 
51
51
  `POST /stream_run` 使用工作流流式协议,事件类型包括 `workflow_start`、`workflow_end`、`error`、`ping`;请求头 `X-Workflow-Stream-Mode: debug` 会额外输出 `node_start`、`node_end`。
52
52
 
53
+ 每次运行可以预先生成 `X-Run-Id`;调用 `POST /cancel/{run_id}` 后,应以服务端返回的取消状态为准。流式执行只有收到 `workflow_end` 才算完成,`node_end` 是节点调试信息。
54
+
55
+ ## 按项目启用断点续跑
56
+
57
+ 普通项目无需数据库表或持久化配置。只有用户明确要求本项目跨重启恢复时,Agent 才为**该项目**生成版本化 SQL 迁移文件,核对目标项目与环境后执行,并创建 `config/workflow-runtime.json`:
58
+
59
+ ```json
60
+ {
61
+ "durability": {
62
+ "enabled": true,
63
+ "graph_version": "v1"
64
+ }
65
+ }
66
+ ```
67
+
68
+ 项目数据库由 `licos-platform-sdk` 的 database 接口访问。迁移文件放在该用户项目内,由 Agent 根据下列运行时契约生成;不要在 AIOS 仓库预置通用迁移,也不要把建表 SQL 放进节点代码或运行时代码:
69
+
70
+ - `public.workflow_instances`:`instance_id text` 主键;`workspace_id`、`project_id`、`environment`、`owner_user_id`、`graph_version`、`input_hash`、`input_data`、`status`、`last_run_id` 均为非空 `text`;`lease_until_ms`、`created_at_ms`、`updated_at_ms` 为非空 `bigint`,租约默认 0;`output_data`、`error_message` 为可空 `text`。
71
+ - `public.workflow_checkpoints`:`thread_id`、`checkpoint_ns`、`checkpoint_id` 为非空 `text` 复合主键;`thread_id` 外键引用 `workflow_instances.instance_id` 并级联删除;`run_id`、`checkpoint_type`、`checkpoint_data`、`metadata_type`、`metadata_data` 为非空 `text`,`parent_checkpoint_id` 为可空 `text`。增加 `(thread_id, checkpoint_ns, checkpoint_id DESC)` 索引。
72
+ - `public.workflow_pending_writes`:`thread_id`、`checkpoint_ns`、`checkpoint_id`、`task_id` 为非空 `text`,`write_idx` 为非空 `integer`,五列组成复合主键;`run_id`、`channel`、`value_type`、`value_data`、`task_path` 为非空 `text`。不要给 pending writes 到检查点加外键:LangGraph 可能在对应检查点事务提交前写入 pending writes。删除实例线程时运行时会先清理 pending writes,再清理检查点。
73
+ - 对检查点与 pending writes 的 `INSERT`/`UPDATE` 加同一个数据库触发器:锁定对应的实例行(`SELECT ... FOR SHARE`),只有 `last_run_id` 等于待写行的 `run_id`、`status = 'running'`,且 `lease_until_ms` 晚于数据库当前时间(毫秒)时才能写入;否则拒绝。行锁要和取消/认领实例的更新互斥,避免检查点检查通过后才提交取消,旧运行仍写入。
74
+
75
+ 模板的 `graph.py` 已通过 `workflow_checkpointer()` 按配置编译图;原有项目启用时也须把 `builder.compile()` 改为 `builder.compile(checkpointer=workflow_checkpointer())`。修改图节点、状态 schema 或路由后,应评估旧检查点兼容性,再更新 `graph_version`。版本不兼容的实例不会自动从头执行。
76
+
77
+ 在已选定项目的 CLI 环境中,可以先省略 `--execute` 查看迁移记录,再对目标环境执行。例如 PowerShell:
78
+
79
+ ```powershell
80
+ $migrationSql = Get-Content -Raw 'db/migrations/001_workflow_durability.sql'
81
+ licos-platform database studio-create-migration --title workflow_durability_v1 --env-scope dev --statement $migrationSql --execute
82
+ ```
83
+
84
+ 生产环境要明确改用 `--env-scope prod`,不能把开发环境的实例表直接复用到生产环境。
85
+
86
+ 启用后,`POST /run` 和 `POST /stream_run` 必须带稳定的 `X-Workflow-Instance-Id`,每次尝试另带新的 `X-Run-Id`。同一实例 ID 与相同输入重复提交时,已完成的运行返回已保存结果;运行中或失败的实例不会被再次启动。使用下列接口查询、显式恢复或取消:
87
+
88
+ 流式连接断开后,持久化执行会继续在服务端运行;页面会记住该项目最近一次实例 ID,重新打开后可查询状态。普通未启用持久化的流式执行在连接断开时会取消。进程重启后,运行中的实例在租约过期时显示为 `interrupted`,且只有已有检查点的实例可以恢复。
89
+
90
+ - `GET /workflow/instances/{instance_id}`:读取状态、图版本、最近 `run_id`、输出和错误。
91
+ - `POST /workflow/instances/{instance_id}/resume`:仅对失败或中断实例恢复,沿用已保存的 LangGraph 检查点;请求需带新的 `X-Run-Id`。
92
+ - `POST /workflow/instances/{instance_id}/cancel`:取消实例,禁止自动恢复。
93
+
94
+ 这三个 ID 含义不同:`workflow_instance_id` 是一项业务流程的稳定 ID;`run_id` 是某次执行尝试的追踪 ID;`runtime_instance_id` 是部署容器 ID。数据库和接口均以已验证的用户、工作区、项目和环境限制访问。
95
+
96
+ ### 外部业务写入
97
+
98
+ MES、ERP、审批等有副作用的节点必须使用稳定幂等键。推荐由 `workflow_instance_id`、固定节点 ID 和业务操作号组成,例如 `工单号:approve_order:审批号`;同一业务操作重试时必须复用同一键。节点应先调用外部系统的幂等写入接口,再把结果写入图状态。**检查点不能覆盖“外部写入成功、检查点尚未保存”之间的故障窗口。**
99
+
100
+ 若外部系统不支持幂等键,节点在重试前应查询业务操作结果;结果不确定时停止运行并由业务规则决定补偿或人工处理,不自动重复写入。只读节点可以按外部接口的超时与重试规则重试;有副作用的节点只在写入接口有明确幂等保证时自动重试。
101
+
53
102
  `/agent/canvas` 返回工作流画布结构,`/agent/canvas_submit` 接收前端编辑后的 `after_canvas` 并生成给 Agent 执行源码修改的 `QueryDiff` 文本。
54
103
 
55
104
  ## 文件输入输出
@@ -4,7 +4,7 @@ version = "0.1.0"
4
4
  description = "LICOS LangGraph workflow project"
5
5
  requires-python = ">=3.12"
6
6
  dependencies = [
7
- "licos-agent-runtime>=0.3.4",
7
+ "licos-agent-runtime>=0.3.6",
8
8
  "licos-dev-sdk>=0.4.9",
9
9
  ]
10
10
 
@@ -1,2 +1,2 @@
1
- licos-agent-runtime>=0.3.4
1
+ licos-agent-runtime>=0.3.6
2
2
  licos-dev-sdk>=0.4.9
@@ -5,6 +5,8 @@ from typing import Any, TypedDict
5
5
  from langgraph.graph import END, START, StateGraph
6
6
  from pydantic import BaseModel, Field
7
7
 
8
+ from licos_agent_runtime.workflow_durability import workflow_checkpointer
9
+
8
10
 
9
11
  class WorkflowInput(BaseModel):
10
12
  topic: str = Field(default="", description="工作流输入主题")
@@ -41,4 +43,4 @@ def create_graph(_ctx: Any = None) -> Any:
41
43
  )
42
44
  builder.add_edge(START, "generate_answer")
43
45
  builder.add_edge("generate_answer", END)
44
- return builder.compile()
46
+ return builder.compile(checkpointer=workflow_checkpointer())
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kmlckj/licos-ai-cli",
3
- "version": "1.4.5",
3
+ "version": "1.4.7",
4
4
  "description": "LICOS AI coding workspace CLI - project template engine and dev tools",
5
5
  "license": "MIT",
6
6
  "author": "kmlckj",