create-windy 0.6.7 → 0.6.8
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.
- package/README.md +2 -2
- package/dist/cli.js +7 -72
- package/package.json +1 -1
- package/template/.windy-template.json +2 -2
- package/template/apps/agent-server/README.md +4 -4
- package/template/apps/server/src/data-access/drizzle-predicate.ts +16 -6
- package/template/docs/architecture/ai-egress.md +1 -1
- package/template/docs/architecture/ai-runtime-readiness.md +2 -2
- package/template/docs/architecture/ai-runtime.md +15 -15
- package/template/docs/architecture/module-secret-resolution.md +4 -4
- package/template/docs/architecture/report-staging.md +1 -1
- package/template/docs/development/custom-login-page.md +3 -3
- package/template/docs/license/license-offline-activation-code.md +2 -2
- package/template/docs/platform/agent-runtime.md +4 -4
- package/template/docs/platform/document-ai-runtime.md +3 -3
- package/template/docs/platform/speech-ai-runtime.md +1 -1
- package/template/docs/platform/vision-ai-runtime.md +1 -1
- package/template/docs/product/built-in-roles.md +9 -1
package/README.md
CHANGED
|
@@ -137,7 +137,7 @@ bun run windy update --dry-run
|
|
|
137
137
|
bun run windy update
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
-
`0.
|
|
140
|
+
`0.6.6` 是 Starter 更新的最低支持基线。更新器不检查 Git 工作区是否干净:只规划
|
|
141
141
|
目标版本实际变更的受管文件,从 source Project Lock 指向的精确 npm artifact 重建
|
|
142
142
|
Base,并以 Base/Ours/Theirs 合并共享脚手架。未触及的业务修改不会进入更新判断;
|
|
143
143
|
`package.json` 使用字段级合并;已发布 migration 只允许追加;冲突发生时不写项目,
|
|
@@ -146,7 +146,7 @@ Base,并以 Base/Ours/Theirs 合并共享脚手架。未触及的业务修改
|
|
|
146
146
|
|
|
147
147
|
受管清单使用 schema v4:`hash` 冻结下游实际正文,`artifactHash` 在两者不同时记录
|
|
148
148
|
公开模板基线;无正文的 missing tombstone 记住客户删除的 `project-owned` 路径。
|
|
149
|
-
低于 `0.
|
|
149
|
+
低于 `0.6.6` 的 Project Lock、旧清单 schema、损坏的 artifact lineage 或 recipe
|
|
150
150
|
缺口都会在写文件前 fail closed,不提供旧状态的自动迁移路径。
|
|
151
151
|
|
|
152
152
|
生成后的整个 `apps/web/src` 与整个 `apps/server/src/app` 都是 project-owned。普通
|
package/dist/cli.js
CHANGED
|
@@ -7716,82 +7716,17 @@ async function diagnoseProject(projectDirectory, repair = false) {
|
|
|
7716
7716
|
}
|
|
7717
7717
|
|
|
7718
7718
|
// src/update/recipes.ts
|
|
7719
|
-
var minimumSupportedUpdateVersion = "0.
|
|
7719
|
+
var minimumSupportedUpdateVersion = "0.6.6";
|
|
7720
7720
|
var recipes = [
|
|
7721
|
-
{
|
|
7722
|
-
id: "starter-0.3.17-to-0.3.18",
|
|
7723
|
-
from: "0.3.17",
|
|
7724
|
-
to: "0.3.18"
|
|
7725
|
-
},
|
|
7726
|
-
{
|
|
7727
|
-
id: "starter-0.3.18-to-0.3.19",
|
|
7728
|
-
from: "0.3.18",
|
|
7729
|
-
to: "0.3.19"
|
|
7730
|
-
},
|
|
7731
|
-
{
|
|
7732
|
-
id: "starter-0.3.19-to-0.4.0",
|
|
7733
|
-
from: "0.3.19",
|
|
7734
|
-
to: "0.4.0"
|
|
7735
|
-
},
|
|
7736
|
-
{
|
|
7737
|
-
id: "starter-0.4.0-to-0.4.1",
|
|
7738
|
-
from: "0.4.0",
|
|
7739
|
-
to: "0.4.1"
|
|
7740
|
-
},
|
|
7741
|
-
{
|
|
7742
|
-
id: "starter-0.4.1-to-0.5.0",
|
|
7743
|
-
from: "0.4.1",
|
|
7744
|
-
to: "0.5.0"
|
|
7745
|
-
},
|
|
7746
|
-
{
|
|
7747
|
-
id: "starter-0.5.0-to-0.5.1",
|
|
7748
|
-
from: "0.5.0",
|
|
7749
|
-
to: "0.5.1"
|
|
7750
|
-
},
|
|
7751
|
-
{
|
|
7752
|
-
id: "starter-0.5.1-to-0.5.2",
|
|
7753
|
-
from: "0.5.1",
|
|
7754
|
-
to: "0.5.2"
|
|
7755
|
-
},
|
|
7756
|
-
{
|
|
7757
|
-
id: "starter-0.5.2-to-0.6.0",
|
|
7758
|
-
from: "0.5.2",
|
|
7759
|
-
to: "0.6.0"
|
|
7760
|
-
},
|
|
7761
|
-
{
|
|
7762
|
-
id: "starter-0.6.0-to-0.6.1",
|
|
7763
|
-
from: "0.6.0",
|
|
7764
|
-
to: "0.6.1"
|
|
7765
|
-
},
|
|
7766
|
-
{
|
|
7767
|
-
id: "starter-0.6.1-to-0.6.2",
|
|
7768
|
-
from: "0.6.1",
|
|
7769
|
-
to: "0.6.2"
|
|
7770
|
-
},
|
|
7771
|
-
{
|
|
7772
|
-
id: "starter-0.6.2-to-0.6.3",
|
|
7773
|
-
from: "0.6.2",
|
|
7774
|
-
to: "0.6.3"
|
|
7775
|
-
},
|
|
7776
|
-
{
|
|
7777
|
-
id: "starter-0.6.3-to-0.6.4",
|
|
7778
|
-
from: "0.6.3",
|
|
7779
|
-
to: "0.6.4"
|
|
7780
|
-
},
|
|
7781
|
-
{
|
|
7782
|
-
id: "starter-0.6.4-to-0.6.5",
|
|
7783
|
-
from: "0.6.4",
|
|
7784
|
-
to: "0.6.5"
|
|
7785
|
-
},
|
|
7786
|
-
{
|
|
7787
|
-
id: "starter-0.6.5-to-0.6.6",
|
|
7788
|
-
from: "0.6.5",
|
|
7789
|
-
to: "0.6.6"
|
|
7790
|
-
},
|
|
7791
7721
|
{
|
|
7792
7722
|
id: "starter-0.6.6-to-0.6.7",
|
|
7793
7723
|
from: "0.6.6",
|
|
7794
7724
|
to: "0.6.7"
|
|
7725
|
+
},
|
|
7726
|
+
{
|
|
7727
|
+
id: "starter-0.6.7-to-0.6.8",
|
|
7728
|
+
from: "0.6.7",
|
|
7729
|
+
to: "0.6.8"
|
|
7795
7730
|
}
|
|
7796
7731
|
];
|
|
7797
7732
|
function resolveRecipeChain(sourceVersion, targetVersion) {
|
|
@@ -8246,7 +8181,7 @@ async function deriveDockerfilePlans(files, snapshots, paths, targetWorkspaceMan
|
|
|
8246
8181
|
continue;
|
|
8247
8182
|
const source = new TextDecoder().decode(dockerSource);
|
|
8248
8183
|
if (!hasDockerfileCopyAnchors(source, target)) {
|
|
8249
|
-
dockerPlan.conflict = "Dockerfile \u7F3A\u5C11 0.
|
|
8184
|
+
dockerPlan.conflict = "Dockerfile \u7F3A\u5C11 0.6.6 \u57FA\u7EBF\u7684 COPY \u951A\u70B9\uFF0C\u5DF2\u505C\u6B62\u81EA\u52A8\u8FC1\u79FB\u65E7\u683C\u5F0F";
|
|
8250
8185
|
continue;
|
|
8251
8186
|
}
|
|
8252
8187
|
let next;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Windy Agent Server
|
|
2
2
|
|
|
3
|
-
Python 3.12 Agent 运行时。HTTP 层只公开
|
|
3
|
+
Python 3.12 Agent 运行时。HTTP 层只公开 Windy 的 canonical Agent 契约;真实业务
|
|
4
4
|
Run 在内部通过 Google ADK 2.5 的 Runner、Session、LlmAgent 和 Event 执行,ADK 类型不会
|
|
5
5
|
越过 `AgentEngineAdapter`。模型调用继续复用受治理的 OpenAI-compatible
|
|
6
6
|
`/chat/completions` Provider。
|
|
@@ -64,12 +64,12 @@ HTTP。Provider 请求包含连接和总超时、响应大小限制、错误脱
|
|
|
64
64
|
readiness。缺少 URL/Model 时回退
|
|
65
65
|
未配置的 `AdkEngineAdapter` 并返回 unavailable,不调用模型。测试另使用
|
|
66
66
|
`DeterministicEngineAdapter`。每个 ADK Tool 只声明 Operation 已允许的 Key;其执行
|
|
67
|
-
函数只回调
|
|
67
|
+
函数只回调 Windy Tool Host,并携带当前 Run 的 opaque Execution Grant。
|
|
68
68
|
|
|
69
69
|
未设置 `AGENT_RUN_STORE_PATH` 时使用的 `InMemoryRunStore` **仅用于 deterministic
|
|
70
70
|
测试**。配置路径后使用有界 SQLite Store,可在单副本重启后保留 Run/Event/Result 和
|
|
71
71
|
cursor;多副本部署仍必须替换为共享 Store。Execution Grant 与 Tool 授权由
|
|
72
|
-
|
|
72
|
+
Windy Server 签发和复核,Agent Server 不能自行扩大 Operation 的
|
|
73
73
|
`allowedToolKeys`。
|
|
74
74
|
|
|
75
75
|
每次实际 `/chat/completions` HTTP 调用前,Runtime 会对 Manifest 允许的输入 JSON
|
|
@@ -3,12 +3,16 @@ import type { DataScopeQuerySpecification } from "./query-specification.js";
|
|
|
3
3
|
|
|
4
4
|
export class DataScopeBindingError extends Error {}
|
|
5
5
|
|
|
6
|
+
export interface DrizzleDataScopeColumn {
|
|
7
|
+
getSQL(): unknown;
|
|
8
|
+
}
|
|
9
|
+
|
|
6
10
|
export interface DrizzleDataScopeBinding {
|
|
7
|
-
readonly ownerId?:
|
|
11
|
+
readonly ownerId?: DrizzleDataScopeColumn;
|
|
8
12
|
readonly tenant?:
|
|
9
|
-
| { readonly mode: "column"; readonly column:
|
|
13
|
+
| { readonly mode: "column"; readonly column: DrizzleDataScopeColumn }
|
|
10
14
|
| { readonly mode: "fixed"; readonly tenantId: string };
|
|
11
|
-
readonly dimensions?: Readonly<Record<string,
|
|
15
|
+
readonly dimensions?: Readonly<Record<string, DrizzleDataScopeColumn>>;
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
export function compileDrizzleDataScopePredicate(
|
|
@@ -28,13 +32,13 @@ export function compileDrizzleDataScopePredicate(
|
|
|
28
32
|
if (tenant.tenantId === branch.tenantId) return undefined;
|
|
29
33
|
continue;
|
|
30
34
|
}
|
|
31
|
-
predicates.push(eq(tenant.column, branch.tenantId));
|
|
35
|
+
predicates.push(eq(drizzleColumn(tenant.column), branch.tenantId));
|
|
32
36
|
}
|
|
33
37
|
if (branch.kind === "owner") {
|
|
34
38
|
if (!binding.ownerId) {
|
|
35
39
|
throw new DataScopeBindingError("scope binding missing ownerId");
|
|
36
40
|
}
|
|
37
|
-
predicates.push(eq(binding.ownerId, branch.ownerId));
|
|
41
|
+
predicates.push(eq(drizzleColumn(binding.ownerId), branch.ownerId));
|
|
38
42
|
}
|
|
39
43
|
if (branch.kind === "dimension") {
|
|
40
44
|
const column = binding.dimensions?.[branch.dimension];
|
|
@@ -43,8 +47,14 @@ export function compileDrizzleDataScopePredicate(
|
|
|
43
47
|
`scope binding missing dimension: ${branch.dimension}`,
|
|
44
48
|
);
|
|
45
49
|
}
|
|
46
|
-
if (branch.values.length)
|
|
50
|
+
if (branch.values.length) {
|
|
51
|
+
predicates.push(inArray(drizzleColumn(column), branch.values));
|
|
52
|
+
}
|
|
47
53
|
}
|
|
48
54
|
}
|
|
49
55
|
return or(...predicates) || sql<boolean>`false`;
|
|
50
56
|
}
|
|
57
|
+
|
|
58
|
+
function drizzleColumn(column: DrizzleDataScopeColumn): AnyColumn {
|
|
59
|
+
return column as unknown as AnyColumn;
|
|
60
|
+
}
|
|
@@ -72,7 +72,7 @@ OpenAI-compatible Adapter 只使用 Agent Server 启动配置的一个 Endpoint
|
|
|
72
72
|
配置还必须通过 `AI_PROVIDER_HTTPS_HOST_ALLOWLIST` 的精确 Host 匹配;不支持通配符、
|
|
73
73
|
scheme、port 或重复 Host。内网 HTTP 继续受既有私有地址校验约束。
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
Windy Server 向 Agent Server 只发送 Operation 的 policy mode 与 Deployment
|
|
76
76
|
Key。Agent Server 在发出模型请求前核对:
|
|
77
77
|
|
|
78
78
|
1. policy 必须是 `configured-endpoint`;
|
|
@@ -12,7 +12,7 @@ deployment pin 和真实 `/health/ready` snapshot 投影新版 Operation;未
|
|
|
12
12
|
|
|
13
13
|
## 目标
|
|
14
14
|
|
|
15
|
-
AI Runtime Readiness V1 为
|
|
15
|
+
AI Runtime Readiness V1 为 Windy Server、Module Operation Host 和各独立
|
|
16
16
|
Runtime 提供同一套失败关闭契约。它回答的是:
|
|
17
17
|
|
|
18
18
|
> 当前这个 Operation 能否在一个已经过真实探测、身份和 release 均未漂移的
|
|
@@ -440,7 +440,7 @@ Readiness 不替代以下权威检查:
|
|
|
440
440
|
- Provider egress、DLP 和 Tool network policy;
|
|
441
441
|
- Run 幂等、取消、审计和输出校验。
|
|
442
442
|
|
|
443
|
-
这些 Guard 仍由
|
|
443
|
+
这些 Guard 仍由 Windy Server 在每次执行的相应阶段重新检查。对未授权调用方,
|
|
444
444
|
Host 不应通过 readiness 暴露跨模块或跨租户的 Deployment 细节。
|
|
445
445
|
|
|
446
446
|
Readiness 也不是 GPU、CPU、显存、队列或并发槽位的资源预留。resource limits 描述该
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Windy AI Runtime 架构
|
|
2
2
|
|
|
3
3
|
更新时间:2026-07-31。
|
|
4
4
|
|
|
@@ -18,7 +18,7 @@ Vision 已提供 `agent.vision` 的多图片受控输入、像素限制、逐次
|
|
|
18
18
|
|
|
19
19
|
## 目标
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Windy 为生成项目提供可选的 AI Runtime。它统一治理模型 Deployment、业务 Operation、Feature Flag、RBAC Permission、License、Audit、Secret、用量和离线部署,但不自行重做通用 Agent Framework、LLM Router、OCR 引擎或语音模型。
|
|
22
22
|
|
|
23
23
|
首期目标:
|
|
24
24
|
|
|
@@ -34,14 +34,14 @@ Southwind AI 为生成项目提供可选的 AI Runtime。它统一治理模型 D
|
|
|
34
34
|
|
|
35
35
|
## 核心决策
|
|
36
36
|
|
|
37
|
-
1. Agent Runtime 是
|
|
37
|
+
1. Agent Runtime 是 Windy 的官方可选底座能力,不是每个业务 Module 自行实现的功能。
|
|
38
38
|
2. Agent Server 独立部署,首期使用 Python ADK;ADK 只属于内部 Implementation。
|
|
39
39
|
3. 首个文本切片由 Agent Server 内置 OpenAI-compatible Adapter;需要多 Provider
|
|
40
40
|
路由、fallback 与集中限流时,再引入独立自托管 LiteLLM Proxy。
|
|
41
41
|
4. OCR 和文档解析由独立 Document AI Server 执行,不放入 Agent Server 或 LiteLLM。
|
|
42
42
|
5. ASR、TTS 和 AI Dictation 由独立 Speech Server 执行;实时 Agent 会话由 Agent Server 编排。
|
|
43
43
|
6. 文本 LLM、VLM 和 Agent 输出使用 SSE;实时音频/视频需要双向传输,使用 WebSocket。
|
|
44
|
-
7.
|
|
44
|
+
7. Windy Server 是身份、Feature、Permission、License、数据范围、Tool 授权和 Audit 的事实源。
|
|
45
45
|
8. 所有业务文件通过 `ArtifactRef` 传递,不在跨服务 DTO 中携带大型 Base64 文件或本地绝对路径。
|
|
46
46
|
|
|
47
47
|
## 总体拓扑
|
|
@@ -51,7 +51,7 @@ Southwind AI 为生成项目提供可选的 AI Runtime。它统一治理模型 D
|
|
|
51
51
|
│
|
|
52
52
|
│ AgentOperation / DocumentOperation / SpeechOperation
|
|
53
53
|
▼
|
|
54
|
-
|
|
54
|
+
Windy Server
|
|
55
55
|
├── Feature / RBAC / License / Audit / Data Scope
|
|
56
56
|
├── AI Deployment Registry
|
|
57
57
|
├── Agent Tool Host
|
|
@@ -81,7 +81,7 @@ Southwind AI Server
|
|
|
81
81
|
|
|
82
82
|
## Module 与部署职责
|
|
83
83
|
|
|
84
|
-
###
|
|
84
|
+
### Windy Server
|
|
85
85
|
|
|
86
86
|
拥有:
|
|
87
87
|
|
|
@@ -109,12 +109,12 @@ Southwind AI Server
|
|
|
109
109
|
- ADK Runner、Workflow、Session、Checkpoint、Eval;
|
|
110
110
|
- Agent、Workflow 和 Prompt Release;
|
|
111
111
|
- Run 生命周期、取消、恢复和 canonical event;
|
|
112
|
-
- ADK Event 到
|
|
112
|
+
- ADK Event 到 Windy Event 的转换;
|
|
113
113
|
- Agent Step、Prompt Version、Tool Call 和模型 attempt 的关联;
|
|
114
114
|
- 开发环境 ADK Web;
|
|
115
115
|
- 实时 Agent 会话编排。
|
|
116
116
|
|
|
117
|
-
Agent Server 不直接访问业务 Repository。模型产生 Tool Call 只表示执行意图;每次真实 Tool 执行都必须回到
|
|
117
|
+
Agent Server 不直接访问业务 Repository。模型产生 Tool Call 只表示执行意图;每次真实 Tool 执行都必须回到 Windy Tool Host,重新检查当前 Feature、License、Permission 和数据范围。
|
|
118
118
|
|
|
119
119
|
### LiteLLM Proxy
|
|
120
120
|
|
|
@@ -187,7 +187,7 @@ credential 删除 scope,缺少 credential 时如实保留 Host TTL cleanup pen
|
|
|
187
187
|
Document、Speech 与 Embedding Interface 已分别由 `./document`、`./speech`、
|
|
188
188
|
`./embedding` 子路径交付。
|
|
189
189
|
|
|
190
|
-
npm Module 数量与部署进程数量是两个不同维度。
|
|
190
|
+
npm Module 数量与部署进程数量是两个不同维度。Windy Server、Agent Server、
|
|
191
191
|
Document AI Server 和 Speech Server 仍独立部署:它们具有不同的协议、资源和故障域;
|
|
192
192
|
业务侧则只学习一个稳定入口。`ai-client` 内部通过 Agent、Document、Speech Adapter
|
|
193
193
|
隔离远端 Implementation,不能把 ADK、LiteLLM、PaddleOCR 或 Provider SDK 类型暴露给业务。
|
|
@@ -379,7 +379,7 @@ Endpoint 配置属于高风险管理动作,必须具备独立 Permission 和
|
|
|
379
379
|
|
|
380
380
|
SSE 是单向 Server-to-Client 协议。创建、取消、审批、恢复和 Tool continuation 使用独立 HTTP command,不在 SSE 连接中反向发送。
|
|
381
381
|
|
|
382
|
-
|
|
382
|
+
Windy Server 与 Agent Server 之间使用本节定义的 canonical SSE;Agent Server 调用 LiteLLM 的文本 LLM/VLM 时使用 OpenAI-compatible SSE streaming。Provider 专有流协议在 LiteLLM Adapter 内终止,不能越过该 Seam。VLM 的图片或视频作为请求 Artifact 发送,模型的文本与结构化响应仍通过 SSE 返回。
|
|
383
383
|
|
|
384
384
|
实时语音和视频需要客户端与服务端同时发送媒体帧,因此使用 WebSocket,不属于本节 SSE 约束。
|
|
385
385
|
|
|
@@ -663,7 +663,7 @@ type DictationEvent =
|
|
|
663
663
|
- 级联:ASR → ADK Agent/LLM → TTS;
|
|
664
664
|
- 原生双向模型:音频/视频 ⇄ Realtime Model。
|
|
665
665
|
|
|
666
|
-
客户端先向
|
|
666
|
+
客户端先向 Windy Server 创建 Live Session 并通过 Guard,再使用短时、绑定 Session 和 audience 的凭证连接 Agent Server WebSocket。Tool Call 仍回到 Windy Tool Host 二次授权。
|
|
667
667
|
|
|
668
668
|
首期不新增独立 Realtime Server。连接规模、电话线路、WebRTC 或媒体转码成为真实需求后,再把媒体数据面拆出。
|
|
669
669
|
|
|
@@ -703,7 +703,7 @@ published version 不可原地修改。每次 Run 固定:
|
|
|
703
703
|
|
|
704
704
|
首期优先使用代码或 YAML、Git、Eval 和不可变 Release。只有出现非开发人员在线编辑的真实需求后,再扩展 diff、审批、回滚、fixture、route 对比和发布管理。
|
|
705
705
|
|
|
706
|
-
生产 Trace 优先输出到客户本地 OTel Collector 与 Jaeger/Tempo。
|
|
706
|
+
生产 Trace 优先输出到客户本地 OTel Collector 与 Jaeger/Tempo。Windy 控制面提供脱敏 Run 摘要和受权限保护的 Trace 入口,不复制 ADK Web。
|
|
707
707
|
|
|
708
708
|
生产默认不持久化完整 Prompt、响应、音频、图片或 Tool 参数。明文诊断需要专门 Feature、Permission、加密、脱敏、TTL 和访问审计。
|
|
709
709
|
|
|
@@ -720,12 +720,12 @@ published version 不可原地修改。每次 Run 固定:
|
|
|
720
720
|
| TTS | 输入字符数、输出音频秒数、GPU 时间 |
|
|
721
721
|
| Live | Session 时长、输入/输出音频秒数、LLM token、Tool 次数 |
|
|
722
722
|
|
|
723
|
-
每条事实标记 `provider-reported`、`estimated` 或 `unknown`;缺失不能记为零。成本绑定调用时的价格快照。LiteLLM 保存 Provider/Deployment 原始事实,Agent Server 保存 Run/Step 归属,Document AI 和 Speech Server 保存各自模态事实,
|
|
723
|
+
每条事实标记 `provider-reported`、`estimated` 或 `unknown`;缺失不能记为零。成本绑定调用时的价格快照。LiteLLM 保存 Provider/Deployment 原始事实,Agent Server 保存 Run/Step 归属,Document AI 和 Speech Server 保存各自模态事实,Windy 通过共享 invocation ID 汇总展示。
|
|
724
724
|
|
|
725
725
|
## 安全与授权
|
|
726
726
|
|
|
727
727
|
- 浏览器和普通业务前端不能直接使用 LiteLLM master key;
|
|
728
|
-
-
|
|
728
|
+
- Windy Server 在发起 Run 前执行 License → Feature → Permission Guard;
|
|
729
729
|
- Remote Runtime 只接受短时、限 audience、限 Operation、绑定 actor、run 和 expiry 的 Execution Grant;
|
|
730
730
|
- Grant 不能携带长期有效的 Permission 列表作为授权事实;
|
|
731
731
|
- Tool 执行、人工批准后的继续和后台重试都重新读取当前授权;
|
|
@@ -797,7 +797,7 @@ fail closed。开发 ADK Web 已作为 localhost-only 的受控调试入口交
|
|
|
797
797
|
- 文本 LLM、VLM 和 Agent 输出统一通过 canonical SSE;
|
|
798
798
|
- SSE 断线后使用 cursor 恢复,不重新执行模型调用;
|
|
799
799
|
- Feature、Permission、License 任一拒绝都会 fail-closed;
|
|
800
|
-
- 模型 Tool Call 不能绕过
|
|
800
|
+
- 模型 Tool Call 不能绕过 Windy Tool Host;
|
|
801
801
|
- 同一 Run 能关联 Audit、ADK Trace、LiteLLM attempt 和 Usage;
|
|
802
802
|
- 本地/内网模型可配置协议、主机、端口和 Base Path;
|
|
803
803
|
- 完全断网环境仍可运行已配置的本地 LLM、OCR 和 Speech Operation;
|
|
@@ -221,14 +221,14 @@ Resolver 不会被调用。
|
|
|
221
221
|
泄漏,但不能识别回调返回的其它未知凭据,也不能把故意通过网络或其它副作用发送凭据的
|
|
222
222
|
恶意模块变成安全代码。这些边界必须继续通过代码审查、模块来源治理和网络策略控制。
|
|
223
223
|
|
|
224
|
-
##
|
|
224
|
+
## SMB / SFTP 业务模块接入示例
|
|
225
225
|
|
|
226
|
-
|
|
226
|
+
业务项目升级到包含该契约的 Windy 版本后,按以下方式接入,不需要修改 Windy 的配置
|
|
227
227
|
Registry 或 Agent Tool Runtime:
|
|
228
228
|
|
|
229
|
-
1. 在拥有 SMB/SFTP
|
|
229
|
+
1. 在拥有 SMB/SFTP 同步能力的业务 Module Manifest 分别声明 password/private-key
|
|
230
230
|
handle、稳定 connection/purpose,以及同基础 Key Feature、Permission 和审计动作;
|
|
231
|
-
2.
|
|
231
|
+
2. 在项目的 project-owned `server-composition.ts` 为每个声明添加
|
|
232
232
|
SDK 根导出的 `createModuleSecretBinding()`,生产 Resolver 指向客户批准的 Secret
|
|
233
233
|
Store;
|
|
234
234
|
3. Route/Service 在一次连接操作内使用
|
|
@@ -148,7 +148,7 @@ Starter 会同时裁剪 helper 源码、编译步骤和依赖。非官方镜像
|
|
|
148
148
|
需要自行提供同一 helper;缺失或 RAR5 真实读取失败会返回
|
|
149
149
|
`REPORT_STAGING_UNSUPPORTED_ARCHIVE`,不会回退旧 `bsdtar -x` 或其他外部命令。
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
相较旧的外部命令直解压方案,当前实现保留已由真实 probe 验证的 RAR5 streaming
|
|
152
152
|
reader,但把落盘所有权和逐 write 配额检查收回 Host,并用可严格解析的 framing 取代
|
|
153
153
|
人类可读 listing。V1 callback 刻意不提供 seek/reopen;需要随机 seek 的 RAR4、ZIP 或
|
|
154
154
|
其他格式会 fail closed,当前不承诺与通用 `archive_read_open_filenames` 格式等价。
|
|
@@ -30,13 +30,13 @@ export const loginPageComponent = defineLoginPageComponent(PlatformLoginPage);
|
|
|
30
30
|
## 完整业务页面
|
|
31
31
|
|
|
32
32
|
将业务页面放在同一个 project-owned 目录,例如
|
|
33
|
-
`apps/web/src/app/auth/
|
|
33
|
+
`apps/web/src/app/auth/ProjectLoginPage.vue`,然后只修改 selector:
|
|
34
34
|
|
|
35
35
|
```ts
|
|
36
|
-
import
|
|
36
|
+
import ProjectLoginPage from "./ProjectLoginPage.vue";
|
|
37
37
|
import { defineLoginPageComponent } from "@/pages/auth/login-page-extension";
|
|
38
38
|
|
|
39
|
-
export const loginPageComponent = defineLoginPageComponent(
|
|
39
|
+
export const loginPageComponent = defineLoginPageComponent(ProjectLoginPage);
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
业务 SFC 使用 Vue 3 Composition API 和 TypeScript。认证提交必须复用
|
|
@@ -50,8 +50,8 @@ W1 是同一份 `SignedLicenseV1` 的离线传输编码,用于客户电脑没
|
|
|
50
50
|
|
|
51
51
|
下表由当前固定 V1 测试向量测得。`完整编码字符`包含 `W1`、段分隔连字符和校验字符;Base32 本身不包含易混的 `I/L/O/U`。V1 现在只携带单一 License 版本标记,不再包含数量可变的能力列表。
|
|
52
52
|
|
|
53
|
-
| 样本
|
|
54
|
-
|
|
|
53
|
+
| 样本 | canonical JSON 字节 | 段数 | 完整编码字符 |
|
|
54
|
+
| ------------------------ | ------------------: | ---: | -----------: |
|
|
55
55
|
| 仓库固定 V1 版本标记向量 | 673 | 20 | 519 |
|
|
56
56
|
|
|
57
57
|
因此 W1 仍然只是无 U 盘、无摄像头时的兜底入口,不能承诺 150~300 字符。仅 64 字节 ED25519 签名转为 Base32 就需要约 103 个数据字符,V1 还签入客户、项目、合同、设备、时间、公钥 ID 和 License 版本等完整展示字段。
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
更新时间:2026-07-26。
|
|
4
4
|
|
|
5
5
|
Windy 的 Agent Runtime 是可选平台能力。业务模块声明稳定的 AI Operation 和允许调用的
|
|
6
|
-
Tool;
|
|
6
|
+
Tool;Windy Server 负责身份、Feature、Permission、License、Scope、Execution
|
|
7
7
|
Grant 与审计;独立 Agent Server 只负责模型循环、canonical event 和受限 Tool Host
|
|
8
8
|
回调。业务模块不选择 Provider、模型、Endpoint 或凭据。
|
|
9
9
|
|
|
@@ -94,7 +94,7 @@ host.registerAiOperationHandlers([
|
|
|
94
94
|
放进返回值。`prepare` 只负责把已经过宿主 Guard 的类型化输入转成指令和用户消息。
|
|
95
95
|
|
|
96
96
|
Tool handler 仍通过 `registerToolHandlers` 注册。模型提出 Tool Call 后,Agent Server
|
|
97
|
-
携带短时 opaque grant 回调
|
|
97
|
+
携带短时 opaque grant 回调 Windy Server;受限 Tool Host 会验证:
|
|
98
98
|
|
|
99
99
|
1. grant 是否绑定当前 Run、Operation、Actor 且未过期;
|
|
100
100
|
2. Tool 是否属于 Operation 的 `allowedToolKeys`;
|
|
@@ -106,7 +106,7 @@ Tool 请求不能携带权限列表、License、Scope 或“已授权”标志
|
|
|
106
106
|
|
|
107
107
|
## 跨进程 Limits 契约
|
|
108
108
|
|
|
109
|
-
Manifest 的 Operation limits 同时包含输入、执行时间和输出上限。
|
|
109
|
+
Manifest 的 Operation limits 同时包含输入、执行时间和输出上限。Windy Server
|
|
110
110
|
在调用远端 Agent Server 前先执行文本输入与 Artifact 声明的 `maxInputBytes` 校验;
|
|
111
111
|
跨进程请求逐字段发送 Agent Server 需要再次执行的时长、输入、输出、图片数量与像素
|
|
112
112
|
上限。禁止通过展开 Manifest 对象透传 limits:TypeScript 的结构类型不会在运行时
|
|
@@ -293,7 +293,7 @@ Operation 契约。
|
|
|
293
293
|
|
|
294
294
|
## 客户端协议
|
|
295
295
|
|
|
296
|
-
浏览器继续使用 `@southwind-ai/ai-client` 访问同源
|
|
296
|
+
浏览器继续使用 `@southwind-ai/ai-client` 访问同源 Windy Server:
|
|
297
297
|
|
|
298
298
|
```text
|
|
299
299
|
POST /api/agent/runs
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Windy 的 Document AI 是可选的独立故障域。业务模块声明稳定的
|
|
6
6
|
`kind=document` Operation,并先把当前 Actor 有权读取的业务资源换成短时
|
|
7
|
-
`ArtifactRef`;
|
|
7
|
+
`ArtifactRef`;Windy Server 完成 Feature、RBAC、License、数据范围、业务对象绑定
|
|
8
8
|
和审计后,才把任务交给 Document Server。未安装或未配置 Document Server 时,对应
|
|
9
9
|
Operation 稳定返回 `CAPABILITY_UNAVAILABLE`,普通业务和文本 Agent 仍可启动。
|
|
10
10
|
|
|
@@ -103,7 +103,7 @@ Repository 证明当前 Actor 可访问真实资源并绑定该文件时才会
|
|
|
103
103
|
|
|
104
104
|
## HTTP 与事件协议
|
|
105
105
|
|
|
106
|
-
浏览器通过同源
|
|
106
|
+
浏览器通过同源 Windy Server 调用:
|
|
107
107
|
|
|
108
108
|
```text
|
|
109
109
|
POST /api/document/runs
|
|
@@ -131,7 +131,7 @@ fail closed;Adapter 的单源 multipart 字段为 `file`,多源字段为重
|
|
|
131
131
|
|
|
132
132
|
### Output Artifact 握手
|
|
133
133
|
|
|
134
|
-
Output Sink 启用时,
|
|
134
|
+
Output Sink 启用时,Windy Host 在调用 Runtime 前冻结:
|
|
135
135
|
|
|
136
136
|
- 预分配的 `runId`;
|
|
137
137
|
- 不含 credential 的 Sink Descriptor,包括 scope、output kind、部署/Release/Offer/
|
|
@@ -16,7 +16,7 @@ Agent 启动。
|
|
|
16
16
|
Repository 回查 `resourceId`、`fileId` 与当前 Actor 的真实关系。
|
|
17
17
|
2. 模块路由调用 `context.aiArtifacts.issue(...)` 换取加密、短时、opaque
|
|
18
18
|
`ArtifactRef`。
|
|
19
|
-
3. `@southwind-ai/ai-client/speech` 只把 Artifact 与领域选项提交到同源
|
|
19
|
+
3. `@southwind-ai/ai-client/speech` 只把 Artifact 与领域选项提交到同源 Windy
|
|
20
20
|
Server。
|
|
21
21
|
4. Server 重新检查 Feature、Permission、License、数据范围、能力摘要和 Artifact
|
|
22
22
|
元数据,并按 Actor + Operation 作用域化幂等键。
|
|
@@ -12,7 +12,7 @@ Windy 的首个 Vision 切片在现有 Agent canonical Run 上增加受治理的
|
|
|
12
12
|
|
|
13
13
|
- 浏览器和业务模块只提交平台签发的 opaque `ArtifactRef`,不能提交 URL、Base64、
|
|
14
14
|
BlobStore Key、宿主路径、模型名或 Provider Endpoint。
|
|
15
|
-
-
|
|
15
|
+
- Windy Server 在 Feature、Permission、License、数据范围通过后重新打开资源,
|
|
16
16
|
校验 MIME、字节数与 SHA-256,再为 Agent Server 轮换短时引用。
|
|
17
17
|
- Agent Server 只从固定 `AI_ARTIFACT_URL` 内网入口读取图片,拒绝调用方 URL。
|
|
18
18
|
- 只接受 JPEG、PNG、WebP;解码后强制检查图片数量、总字节与单图像素。
|
|
@@ -21,6 +21,14 @@ Starter 首次安装提供四个稳定角色。角色 ID 和 code 是升级契
|
|
|
21
21
|
|
|
22
22
|
## 安全边界
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
`dataScope` 和 `departmentIds` 已持久化,用户、示例工单、Agent Tool、导出与受支持的
|
|
25
|
+
后台路径已经接入 Repository 级查询范围强制。列表、总数、详情、更新和删除把同一 scope
|
|
26
|
+
predicate 下推到查询,缺少 nominal `ScopeContext` 或 ownership 绑定时 fail closed;完整
|
|
27
|
+
边界见[Repository 级 Data Scope 强制](../architecture/data-scope-query-enforcement.md)。新增
|
|
28
|
+
Repository 或异步资源仍必须显式登记 `dataAccess`,不能因已有基础设施而默认视为已覆盖。
|
|
29
|
+
|
|
30
|
+
部门负责人基线继续不授予 `system.user.manage` 或 `system.department.manage`。这是最小
|
|
31
|
+
权限的产品默认值,不是用前端隐藏替代服务端 Guard;管理员可按部署需求显式配置自定义
|
|
32
|
+
角色,最终仍受 Feature、Permission 和 Repository scope 共同约束。
|
|
25
33
|
|
|
26
34
|
用户敏感字段策略将 `system.user.read`、`system.user.reveal` 和 `system.user.export` 分为三类能力。普通读取只能取得服务端脱敏结果;明文查看与治理导出即使由超级管理员执行,也必须重新授权并写入关键审计。客户端提交的角色 code、权限数组或展示模式不是授权来源。
|