@tomflow/proflow-platform-host 0.1.21 → 0.1.23
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/CHANGELOG.md +7 -0
- package/DOCS.md +3 -2
- package/dist/deployment/adapter.d.ts +10 -17
- package/dist/deployment/adapter.js +30 -43
- package/dist/deployment/descriptor.d.ts +4 -7
- package/dist/deployment/descriptor.js +4 -8
- package/dist/src/cli.js +0 -4
- package/dist/src/index.d.ts +18 -8
- package/dist/src/index.js +269 -270
- package/dist/src/reconciliation-coordinator.d.ts +37 -0
- package/dist/src/reconciliation-coordinator.js +336 -0
- package/dist/src/role-operations.d.ts +4 -6
- package/dist/src/role-operations.js +37 -12
- package/dist/src/task-observer.d.ts +49 -0
- package/dist/src/task-observer.js +90 -0
- package/package.json +7 -7
- package/proflow.module.json +4 -8
package/CHANGELOG.md
ADDED
package/DOCS.md
CHANGED
|
@@ -17,7 +17,8 @@ ProFlow 的本地 Composition Root(组合根),把 Task、Agent、Execution
|
|
|
17
17
|
|
|
18
18
|
## 依赖的 Module、Contract 和外部资源
|
|
19
19
|
|
|
20
|
-
-
|
|
20
|
+
- 启动依赖只包含 `local-tool-bridge`、`task-orchestration` 和 `agent-runtime`,兼容版本均为 `>=1.0.0 <2.0.0`。
|
|
21
|
+
- Execution 与 Model 是 operation-scoped late-bound dependency;它们不可用时只影响对应 operation,不构成 platform-host 全局启动前置。
|
|
21
22
|
|
|
22
23
|
## 运行形态与生命周期
|
|
23
24
|
|
|
@@ -25,7 +26,7 @@ ProFlow 的本地 Composition Root(组合根),把 Task、Agent、Execution
|
|
|
25
26
|
|
|
26
27
|
## 使用方式
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
满足启动依赖后通过 Platform 生命周期启动;Execution/Model/Provider 等 operation-scoped 依赖在请求时解析,下游从 shared facts 获取端点和凭据路径。
|
|
29
30
|
|
|
30
31
|
## 职责边界与限制
|
|
31
32
|
|
|
@@ -6,7 +6,7 @@ export declare const behaviorAdapter: {
|
|
|
6
6
|
ok: true;
|
|
7
7
|
status: "SUCCEEDED";
|
|
8
8
|
moduleRef: "platform-host";
|
|
9
|
-
moduleVersion: "0.1.
|
|
9
|
+
moduleVersion: "0.1.23";
|
|
10
10
|
data: {
|
|
11
11
|
endpoint: string;
|
|
12
12
|
stateRoot: string;
|
|
@@ -24,7 +24,7 @@ export declare const behaviorAdapter: {
|
|
|
24
24
|
readonly ok: true;
|
|
25
25
|
readonly status: "SUCCEEDED";
|
|
26
26
|
readonly moduleRef: "platform-host";
|
|
27
|
-
readonly moduleVersion: "0.1.
|
|
27
|
+
readonly moduleVersion: "0.1.23";
|
|
28
28
|
};
|
|
29
29
|
observedEffects: string[];
|
|
30
30
|
}>;
|
|
@@ -34,17 +34,10 @@ export declare const behaviorAdapter: {
|
|
|
34
34
|
ok: true;
|
|
35
35
|
status: "SUCCEEDED";
|
|
36
36
|
moduleRef: "platform-host";
|
|
37
|
-
moduleVersion: "0.1.
|
|
37
|
+
moduleVersion: "0.1.23";
|
|
38
38
|
data: {
|
|
39
39
|
setupStatus: "READY";
|
|
40
40
|
runtimeStatus: "RUNNING" | "STOPPED";
|
|
41
|
-
issues?: {
|
|
42
|
-
scope: "RUNTIME";
|
|
43
|
-
code: string;
|
|
44
|
-
message: string;
|
|
45
|
-
relatedModuleRefs: string[];
|
|
46
|
-
nextCommand: string;
|
|
47
|
-
}[];
|
|
48
41
|
};
|
|
49
42
|
};
|
|
50
43
|
observedEffects: never[];
|
|
@@ -55,7 +48,7 @@ export declare const behaviorAdapter: {
|
|
|
55
48
|
ok: true;
|
|
56
49
|
status: "SUCCEEDED";
|
|
57
50
|
moduleRef: "platform-host";
|
|
58
|
-
moduleVersion: "0.1.
|
|
51
|
+
moduleVersion: "0.1.23";
|
|
59
52
|
data: {
|
|
60
53
|
endpoint: string;
|
|
61
54
|
stateRoot: string;
|
|
@@ -73,7 +66,7 @@ export declare const behaviorAdapter: {
|
|
|
73
66
|
ok: true;
|
|
74
67
|
status: "SUCCEEDED";
|
|
75
68
|
moduleRef: "platform-host";
|
|
76
|
-
moduleVersion: "0.1.
|
|
69
|
+
moduleVersion: "0.1.23";
|
|
77
70
|
data: {
|
|
78
71
|
docs: string;
|
|
79
72
|
};
|
|
@@ -86,7 +79,7 @@ export declare const behaviorAdapter: {
|
|
|
86
79
|
ok: true;
|
|
87
80
|
status: "SUCCEEDED";
|
|
88
81
|
moduleRef: "platform-host";
|
|
89
|
-
moduleVersion: "0.1.
|
|
82
|
+
moduleVersion: "0.1.23";
|
|
90
83
|
data: {
|
|
91
84
|
host: string;
|
|
92
85
|
port: number;
|
|
@@ -97,7 +90,7 @@ export declare const behaviorAdapter: {
|
|
|
97
90
|
result: {
|
|
98
91
|
contract: "deployment.result.v1";
|
|
99
92
|
moduleRef: "platform-host";
|
|
100
|
-
moduleVersion: "0.1.
|
|
93
|
+
moduleVersion: "0.1.23";
|
|
101
94
|
ok: false;
|
|
102
95
|
status: "FAILED";
|
|
103
96
|
error: {
|
|
@@ -114,7 +107,7 @@ export declare const behaviorAdapter: {
|
|
|
114
107
|
readonly ok: true;
|
|
115
108
|
readonly status: "SUCCEEDED";
|
|
116
109
|
readonly moduleRef: "platform-host";
|
|
117
|
-
readonly moduleVersion: "0.1.
|
|
110
|
+
readonly moduleVersion: "0.1.23";
|
|
118
111
|
};
|
|
119
112
|
observedEffects: string[];
|
|
120
113
|
} | {
|
|
@@ -123,11 +116,11 @@ export declare const behaviorAdapter: {
|
|
|
123
116
|
readonly ok: true;
|
|
124
117
|
readonly status: "SUCCEEDED";
|
|
125
118
|
readonly moduleRef: "platform-host";
|
|
126
|
-
readonly moduleVersion: "0.1.
|
|
119
|
+
readonly moduleVersion: "0.1.23";
|
|
127
120
|
} | {
|
|
128
121
|
contract: "deployment.result.v1";
|
|
129
122
|
moduleRef: "platform-host";
|
|
130
|
-
moduleVersion: "0.1.
|
|
123
|
+
moduleVersion: "0.1.23";
|
|
131
124
|
ok: false;
|
|
132
125
|
status: "FAILED";
|
|
133
126
|
error: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
-
import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { chmod, mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
4
4
|
import { dirname, join, resolve } from "node:path";
|
|
5
5
|
import { deterministicLoopbackPort, ensureModuleSecretFile, readModuleSharedFacts, writeModuleSharedFacts, } from "@tomflow/proflow-module-contract";
|
|
6
6
|
import { descriptor } from "./descriptor.js";
|
|
@@ -50,32 +50,13 @@ async function readOwnFacts(context) {
|
|
|
50
50
|
const endpoint = factString(facts, "endpoint");
|
|
51
51
|
return endpoint ? { endpoint } : undefined;
|
|
52
52
|
}
|
|
53
|
-
async function dependencies(context) {
|
|
54
|
-
const execution = await readModuleSharedFacts(context, "execution-runtime");
|
|
55
|
-
const model = await readModuleSharedFacts(context, "model-runtime");
|
|
56
|
-
const executionBaseUrl = factString(execution, "endpoint");
|
|
57
|
-
const executionTransportCredentialFile = factString(execution, "transportCredentialFile");
|
|
58
|
-
const modelBaseUrl = factString(model, "endpoint");
|
|
59
|
-
const modelTransportCredentialFile = factString(model, "transportCredentialFile");
|
|
60
|
-
return executionBaseUrl &&
|
|
61
|
-
executionTransportCredentialFile &&
|
|
62
|
-
modelBaseUrl &&
|
|
63
|
-
modelTransportCredentialFile
|
|
64
|
-
? {
|
|
65
|
-
executionBaseUrl,
|
|
66
|
-
executionTransportCredentialFile,
|
|
67
|
-
modelBaseUrl,
|
|
68
|
-
modelTransportCredentialFile,
|
|
69
|
-
}
|
|
70
|
-
: undefined;
|
|
71
|
-
}
|
|
72
53
|
async function running(context) {
|
|
73
54
|
const own = await readOwnFacts(context);
|
|
74
55
|
if (!own)
|
|
75
56
|
return false;
|
|
76
57
|
try {
|
|
77
|
-
return (await fetch(`${own.endpoint}/
|
|
78
|
-
signal: AbortSignal.timeout(
|
|
58
|
+
return (await fetch(`${own.endpoint}/health`, {
|
|
59
|
+
signal: AbortSignal.timeout(2_000),
|
|
79
60
|
})).ok;
|
|
80
61
|
}
|
|
81
62
|
catch {
|
|
@@ -84,21 +65,41 @@ async function running(context) {
|
|
|
84
65
|
}
|
|
85
66
|
async function compose(context) {
|
|
86
67
|
const own = await ownFacts(context);
|
|
87
|
-
const deps = await dependencies(context);
|
|
88
|
-
if (!deps)
|
|
89
|
-
throw new Error("required Execution/Model shared facts are unavailable");
|
|
90
68
|
const { createPlatformHost, parsePlatformHostConfig } = await import("../src/index.js");
|
|
91
69
|
const url = new URL(own.endpoint);
|
|
92
70
|
const host = createPlatformHost({
|
|
71
|
+
resolveLocalToolConnection: async () => {
|
|
72
|
+
const facts = await readModuleSharedFacts(context, "execution-browser-extension");
|
|
73
|
+
const endpoint = factString(facts, "localToolBridgeEndpoint");
|
|
74
|
+
const tokenFile = factString(facts, "localToolHostTokenFile");
|
|
75
|
+
if (!endpoint || !tokenFile)
|
|
76
|
+
return undefined;
|
|
77
|
+
const info = await stat(tokenFile);
|
|
78
|
+
if (process.platform !== "win32" && (info.mode & 0o077) !== 0)
|
|
79
|
+
throw new Error("local tool credential permissions must be owner-only");
|
|
80
|
+
const credential = (await readFile(tokenFile, "utf8")).trim();
|
|
81
|
+
if (credential.length < 32)
|
|
82
|
+
throw new Error("invalid local tool credential");
|
|
83
|
+
return { endpoint, credential };
|
|
84
|
+
},
|
|
85
|
+
resolveOwnerConnection: async (owner) => {
|
|
86
|
+
const facts = await readModuleSharedFacts(context, owner === "execution" ? "execution-runtime" : "model-runtime");
|
|
87
|
+
const baseUrl = factString(facts, "endpoint"), tokenFile = factString(facts, "transportCredentialFile");
|
|
88
|
+
if (!baseUrl || !tokenFile)
|
|
89
|
+
return undefined;
|
|
90
|
+
const info = await stat(tokenFile);
|
|
91
|
+
if (process.platform !== "win32" && (info.mode & 0o077) !== 0)
|
|
92
|
+
throw new Error("owner credential permissions must be owner-only");
|
|
93
|
+
const credential = (await readFile(tokenFile, "utf8")).trim();
|
|
94
|
+
if (credential.length < 32)
|
|
95
|
+
throw new Error("invalid owner credential");
|
|
96
|
+
return { baseUrl, credential };
|
|
97
|
+
},
|
|
93
98
|
config: parsePlatformHostConfig({
|
|
94
99
|
stateRoot: own.stateRoot,
|
|
95
100
|
workspaceRoot: key(context),
|
|
96
101
|
host: url.hostname,
|
|
97
102
|
port: Number(url.port),
|
|
98
|
-
executionBaseUrl: deps.executionBaseUrl,
|
|
99
|
-
executionTransportCredentialFile: deps.executionTransportCredentialFile,
|
|
100
|
-
modelBaseUrl: deps.modelBaseUrl,
|
|
101
|
-
modelTransportCredentialFile: deps.modelTransportCredentialFile,
|
|
102
103
|
gatewayTransportCredentialFile: own.gatewayTransportCredentialFile,
|
|
103
104
|
roles: [],
|
|
104
105
|
}),
|
|
@@ -128,7 +129,6 @@ export const behaviorAdapter = {
|
|
|
128
129
|
};
|
|
129
130
|
},
|
|
130
131
|
status: async (context) => {
|
|
131
|
-
const runtimeDependencies = await dependencies(context);
|
|
132
132
|
return {
|
|
133
133
|
result: {
|
|
134
134
|
...base,
|
|
@@ -137,19 +137,6 @@ export const behaviorAdapter = {
|
|
|
137
137
|
runtimeStatus: (await running(context))
|
|
138
138
|
? "RUNNING"
|
|
139
139
|
: "STOPPED",
|
|
140
|
-
...(runtimeDependencies
|
|
141
|
-
? {}
|
|
142
|
-
: {
|
|
143
|
-
issues: [
|
|
144
|
-
{
|
|
145
|
-
scope: "RUNTIME",
|
|
146
|
-
code: "UPSTREAM_NOT_READY",
|
|
147
|
-
message: "等待 Execution 与 Model Runtime 发布运行所需服务信息",
|
|
148
|
-
relatedModuleRefs: ["execution-runtime", "model-runtime"],
|
|
149
|
-
nextCommand: "platform setup",
|
|
150
|
-
},
|
|
151
|
-
],
|
|
152
|
-
}),
|
|
153
140
|
},
|
|
154
141
|
},
|
|
155
142
|
observedEffects: [],
|
|
@@ -3,7 +3,7 @@ export declare const descriptor: {
|
|
|
3
3
|
readonly contractVersion: "1.0.0";
|
|
4
4
|
readonly moduleRef: "platform-host";
|
|
5
5
|
readonly packageName: "@tomflow/proflow-platform-host";
|
|
6
|
-
readonly moduleVersion: "0.1.
|
|
6
|
+
readonly moduleVersion: "0.1.23";
|
|
7
7
|
readonly kind: "service";
|
|
8
8
|
readonly templateVersion: "1.0.0";
|
|
9
9
|
readonly platformCompatibility: ">=1.0.0 <2.0.0";
|
|
@@ -16,16 +16,13 @@ export declare const descriptor: {
|
|
|
16
16
|
readonly version: "1.0.0";
|
|
17
17
|
}];
|
|
18
18
|
readonly requires: readonly [{
|
|
19
|
-
readonly contractRef: "
|
|
20
|
-
readonly versionRange: ">=1.0.0 <2.0.0";
|
|
21
|
-
}, {
|
|
22
|
-
readonly contractRef: "agent-runtime";
|
|
19
|
+
readonly contractRef: "local-tool-bridge";
|
|
23
20
|
readonly versionRange: ">=1.0.0 <2.0.0";
|
|
24
21
|
}, {
|
|
25
|
-
readonly contractRef: "
|
|
22
|
+
readonly contractRef: "task-orchestration";
|
|
26
23
|
readonly versionRange: ">=1.0.0 <2.0.0";
|
|
27
24
|
}, {
|
|
28
|
-
readonly contractRef: "
|
|
25
|
+
readonly contractRef: "agent-runtime";
|
|
29
26
|
readonly versionRange: ">=1.0.0 <2.0.0";
|
|
30
27
|
}];
|
|
31
28
|
readonly requirements: readonly [{
|
|
@@ -3,7 +3,7 @@ export const descriptor = {
|
|
|
3
3
|
contractVersion: "1.0.0",
|
|
4
4
|
moduleRef: "platform-host",
|
|
5
5
|
packageName: "@tomflow/proflow-platform-host",
|
|
6
|
-
moduleVersion: "0.1.
|
|
6
|
+
moduleVersion: "0.1.23",
|
|
7
7
|
kind: "service",
|
|
8
8
|
templateVersion: "1.0.0",
|
|
9
9
|
platformCompatibility: ">=1.0.0 <2.0.0",
|
|
@@ -19,19 +19,15 @@ export const descriptor = {
|
|
|
19
19
|
],
|
|
20
20
|
requires: [
|
|
21
21
|
{
|
|
22
|
-
contractRef: "
|
|
22
|
+
contractRef: "local-tool-bridge",
|
|
23
23
|
versionRange: ">=1.0.0 <2.0.0",
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
|
-
contractRef: "
|
|
27
|
-
versionRange: ">=1.0.0 <2.0.0",
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
contractRef: "execution",
|
|
26
|
+
contractRef: "task-orchestration",
|
|
31
27
|
versionRange: ">=1.0.0 <2.0.0",
|
|
32
28
|
},
|
|
33
29
|
{
|
|
34
|
-
contractRef: "
|
|
30
|
+
contractRef: "agent-runtime",
|
|
35
31
|
versionRange: ">=1.0.0 <2.0.0",
|
|
36
32
|
},
|
|
37
33
|
],
|
package/dist/src/cli.js
CHANGED
|
@@ -11,10 +11,6 @@ async function main() {
|
|
|
11
11
|
const config = await loadPlatformHostConfig(configPath);
|
|
12
12
|
if (!config.gatewayTransportCredentialFile)
|
|
13
13
|
throw new Error("platform-host requires gatewayTransportCredentialFile for authenticated Gateway transport");
|
|
14
|
-
if (!config.modelTransportCredentialFile)
|
|
15
|
-
throw new Error("platform-host requires modelTransportCredentialFile for authenticated Model Runtime transport");
|
|
16
|
-
if (!config.executionTransportCredentialFile)
|
|
17
|
-
throw new Error("platform-host requires executionTransportCredentialFile for authenticated Execution Runtime transport");
|
|
18
14
|
const host = createPlatformHost({
|
|
19
15
|
config,
|
|
20
16
|
log: (entry) => process.stderr.write(`${JSON.stringify(entry)}\n`),
|
package/dist/src/index.d.ts
CHANGED
|
@@ -4,9 +4,9 @@ declare const configSchema: z.ZodPipe<z.ZodObject<{
|
|
|
4
4
|
workspaceRoot: z.ZodString;
|
|
5
5
|
host: z.ZodDefault<z.ZodString>;
|
|
6
6
|
port: z.ZodDefault<z.ZodNumber>;
|
|
7
|
-
executionBaseUrl: z.ZodPipe<z.ZodPipe<z.ZodURL, z.ZodTransform<URL, string>>, z.ZodTransform<string, URL
|
|
7
|
+
executionBaseUrl: z.ZodOptional<z.ZodPipe<z.ZodPipe<z.ZodURL, z.ZodTransform<URL, string>>, z.ZodTransform<string, URL>>>;
|
|
8
8
|
executionTransportCredentialFile: z.ZodOptional<z.ZodString>;
|
|
9
|
-
modelBaseUrl: z.ZodPipe<z.ZodPipe<z.ZodURL, z.ZodTransform<URL, string>>, z.ZodTransform<string, URL
|
|
9
|
+
modelBaseUrl: z.ZodOptional<z.ZodPipe<z.ZodPipe<z.ZodURL, z.ZodTransform<URL, string>>, z.ZodTransform<string, URL>>>;
|
|
10
10
|
modelTransportCredentialFile: z.ZodOptional<z.ZodString>;
|
|
11
11
|
gatewayTransportCredentialFile: z.ZodOptional<z.ZodString>;
|
|
12
12
|
roles: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
@@ -22,9 +22,9 @@ declare const configSchema: z.ZodPipe<z.ZodObject<{
|
|
|
22
22
|
}, z.core.$strict>, z.ZodTransform<{
|
|
23
23
|
host: string;
|
|
24
24
|
port: number;
|
|
25
|
-
executionBaseUrl
|
|
25
|
+
executionBaseUrl?: string | undefined;
|
|
26
26
|
executionTransportCredentialFile?: string | undefined;
|
|
27
|
-
modelBaseUrl
|
|
27
|
+
modelBaseUrl?: string | undefined;
|
|
28
28
|
modelTransportCredentialFile?: string | undefined;
|
|
29
29
|
gatewayTransportCredentialFile?: string | undefined;
|
|
30
30
|
roles: {
|
|
@@ -40,9 +40,9 @@ declare const configSchema: z.ZodPipe<z.ZodObject<{
|
|
|
40
40
|
workspaceRoot: string;
|
|
41
41
|
host: string;
|
|
42
42
|
port: number;
|
|
43
|
-
executionBaseUrl
|
|
43
|
+
executionBaseUrl?: string | undefined;
|
|
44
44
|
executionTransportCredentialFile?: string | undefined;
|
|
45
|
-
modelBaseUrl
|
|
45
|
+
modelBaseUrl?: string | undefined;
|
|
46
46
|
modelTransportCredentialFile?: string | undefined;
|
|
47
47
|
gatewayTransportCredentialFile?: string | undefined;
|
|
48
48
|
roles: {
|
|
@@ -57,9 +57,9 @@ export declare const parsePlatformHostConfig: (value: unknown) => PlatformHostCo
|
|
|
57
57
|
export declare function loadPlatformHostConfig(path: string): Promise<{
|
|
58
58
|
host: string;
|
|
59
59
|
port: number;
|
|
60
|
-
executionBaseUrl
|
|
60
|
+
executionBaseUrl?: string | undefined;
|
|
61
61
|
executionTransportCredentialFile?: string | undefined;
|
|
62
|
-
modelBaseUrl
|
|
62
|
+
modelBaseUrl?: string | undefined;
|
|
63
63
|
modelTransportCredentialFile?: string | undefined;
|
|
64
64
|
gatewayTransportCredentialFile?: string | undefined;
|
|
65
65
|
roles: {
|
|
@@ -91,6 +91,14 @@ export type PlatformHostStatus = {
|
|
|
91
91
|
model: DependencyReadiness;
|
|
92
92
|
};
|
|
93
93
|
};
|
|
94
|
+
export type OwnerConnectionResolver = (owner: "execution" | "model") => Promise<{
|
|
95
|
+
baseUrl: string;
|
|
96
|
+
credential: string;
|
|
97
|
+
} | undefined>;
|
|
98
|
+
export type LocalToolConnectionResolver = () => Promise<{
|
|
99
|
+
endpoint: string;
|
|
100
|
+
credential: string;
|
|
101
|
+
} | undefined>;
|
|
94
102
|
export type PlatformHostBrowserOwnerPorts = {
|
|
95
103
|
task: {
|
|
96
104
|
getWorkerBinding(taskId: string, roleRef: string): Promise<{
|
|
@@ -222,6 +230,8 @@ export declare function createPlatformHost(input: {
|
|
|
222
230
|
config: PlatformHostConfig;
|
|
223
231
|
log?: (entry: Record<string, unknown>) => void;
|
|
224
232
|
executionCredential?: string;
|
|
233
|
+
resolveOwnerConnection?: OwnerConnectionResolver;
|
|
234
|
+
resolveLocalToolConnection?: LocalToolConnectionResolver;
|
|
225
235
|
}): Readonly<{
|
|
226
236
|
start: () => Promise<{
|
|
227
237
|
host: string;
|