spawnfile 0.1.11 → 0.1.12
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 +13 -2
- package/dist/cli/lifecycleCommands.js +101 -1
- package/dist/cli/modelCommands.js +3 -0
- package/dist/cli/resolveCommandInput.d.ts +19 -0
- package/dist/cli/resolveCommandInput.js +25 -0
- package/dist/cli/runCli.d.ts +4 -1
- package/dist/cli/runCli.js +37 -13
- package/dist/cli/runtimeCommands.js +1 -0
- package/dist/cli/statusCommand.d.ts +42 -0
- package/dist/cli/statusCommand.js +394 -0
- package/dist/cli/surfaceCommands.js +4 -0
- package/dist/compiler/agentSurfaces.js +2 -4
- package/dist/compiler/compileProject.js +19 -10
- package/dist/compiler/containerArtifacts.d.ts +1 -0
- package/dist/compiler/containerArtifacts.js +208 -32
- package/dist/compiler/containerArtifactsPlans.js +7 -4
- package/dist/compiler/containerArtifactsRender.d.ts +7 -1
- package/dist/compiler/containerArtifactsRender.js +6 -0
- package/dist/compiler/containerArtifactsTypes.d.ts +9 -0
- package/dist/compiler/containerEntrypointRender.js +18 -31
- package/dist/compiler/index.d.ts +1 -0
- package/dist/compiler/index.js +1 -0
- package/dist/compiler/moltnetArtifacts.js +5 -0
- package/dist/compiler/moltnetClientConfig.d.ts +1 -1
- package/dist/compiler/moltnetClientConfig.js +3 -16
- package/dist/compiler/moltnetNodeConfig.js +2 -4
- package/dist/compiler/moltnetResolution.js +1 -1
- package/dist/compiler/moltnetRoomMemberships.js +1 -2
- package/dist/compiler/moltnetRuntimeConfig.d.ts +1 -1
- package/dist/compiler/moltnetRuntimeConfig.js +1 -13
- package/dist/compiler/networkBinding.d.ts +14 -0
- package/dist/compiler/networkBinding.js +34 -0
- package/dist/compiler/publishProject.d.ts +13 -0
- package/dist/compiler/publishProject.js +72 -0
- package/dist/compiler/runProject.d.ts +26 -12
- package/dist/compiler/runProject.js +102 -125
- package/dist/compiler/runProjectAuth.d.ts +5 -0
- package/dist/compiler/runProjectAuth.js +98 -0
- package/dist/compiler/runProjectDocker.d.ts +19 -0
- package/dist/compiler/runProjectDocker.js +57 -0
- package/dist/compiler/types.d.ts +1 -2
- package/dist/compiler/upProject.d.ts +6 -0
- package/dist/compiler/upProject.js +42 -8
- package/dist/compiler/view/buildOrganizationView.js +4 -1
- package/dist/compiler/view/declarations.d.ts +4 -0
- package/dist/compiler/view/declarations.js +104 -0
- package/dist/compiler/view/renderNetworks.js +1 -2
- package/dist/compiler/view/renderTree.js +6 -2
- package/dist/compiler/view/types.d.ts +64 -1
- package/dist/deployment/dockerInspect.d.ts +29 -0
- package/dist/deployment/dockerInspect.js +130 -0
- package/dist/deployment/dockerLabels.d.ts +16 -0
- package/dist/deployment/dockerLabels.js +32 -0
- package/dist/deployment/dockerLogs.d.ts +24 -0
- package/dist/deployment/dockerLogs.js +96 -0
- package/dist/deployment/dockerManager.d.ts +59 -0
- package/dist/deployment/dockerManager.js +76 -0
- package/dist/deployment/dockerProbeGateway.d.ts +16 -0
- package/dist/deployment/dockerProbeGateway.js +48 -0
- package/dist/deployment/homeStore.d.ts +19 -0
- package/dist/deployment/homeStore.js +130 -0
- package/dist/deployment/index.d.ts +9 -0
- package/dist/deployment/index.js +9 -0
- package/dist/deployment/names.d.ts +3 -0
- package/dist/deployment/names.js +12 -0
- package/dist/deployment/record.d.ts +76 -0
- package/dist/deployment/record.js +174 -0
- package/dist/deployment/target.d.ts +35 -0
- package/dist/deployment/target.js +96 -0
- package/dist/distribution/buildDistributionReport.d.ts +22 -0
- package/dist/distribution/buildDistributionReport.js +51 -0
- package/dist/distribution/consumeImage.d.ts +29 -0
- package/dist/distribution/consumeImage.js +254 -0
- package/dist/distribution/consumeImageSupport.d.ts +18 -0
- package/dist/distribution/consumeImageSupport.js +63 -0
- package/dist/distribution/distributionReportSchema.d.ts +84 -0
- package/dist/distribution/distributionReportSchema.js +107 -0
- package/dist/distribution/dockerRunner.d.ts +5 -0
- package/dist/distribution/dockerRunner.js +21 -0
- package/dist/distribution/extractImage.d.ts +25 -0
- package/dist/distribution/extractImage.js +96 -0
- package/dist/distribution/fingerprint.d.ts +2 -0
- package/dist/distribution/fingerprint.js +14 -0
- package/dist/distribution/imageRef.d.ts +9 -0
- package/dist/distribution/imageRef.js +65 -0
- package/dist/distribution/imageRuntimeAuth.d.ts +19 -0
- package/dist/distribution/imageRuntimeAuth.js +71 -0
- package/dist/distribution/index.d.ts +24 -0
- package/dist/distribution/index.js +16 -0
- package/dist/distribution/preflight.d.ts +11 -0
- package/dist/distribution/preflight.js +65 -0
- package/dist/distribution/projectImageView.d.ts +8 -0
- package/dist/distribution/projectImageView.js +83 -0
- package/dist/distribution/projectName.d.ts +1 -0
- package/dist/distribution/projectName.js +12 -0
- package/dist/distribution/renderImageInterface.d.ts +30 -0
- package/dist/distribution/renderImageInterface.js +86 -0
- package/dist/distribution/tarReader.d.ts +10 -0
- package/dist/distribution/tarReader.js +69 -0
- package/dist/distribution/types.d.ts +80 -0
- package/dist/distribution/types.js +4 -0
- package/dist/distribution/verifyDistributionReport.d.ts +12 -0
- package/dist/distribution/verifyDistributionReport.js +29 -0
- package/dist/filesystem/paths.d.ts +6 -0
- package/dist/filesystem/paths.js +11 -0
- package/dist/manifest/loadManifest.js +22 -2
- package/dist/manifest/renderSpawnfile.js +2 -4
- package/dist/manifest/schemas.d.ts +17 -41
- package/dist/manifest/surfaceSchemas.d.ts +19 -47
- package/dist/manifest/surfaceSchemas.js +3 -6
- package/dist/report/createReport.d.ts +7 -1
- package/dist/report/createReport.js +28 -1
- package/dist/report/types.d.ts +43 -0
- package/dist/runtime/container.js +0 -16
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/install.d.ts +0 -10
- package/dist/runtime/install.js +0 -45
- package/dist/runtime/openclaw/adapter.js +9 -1
- package/dist/runtime/openclaw/configAuth.d.ts +15 -0
- package/dist/runtime/openclaw/configAuth.js +46 -0
- package/dist/runtime/openclaw/runAuth.d.ts +6 -0
- package/dist/runtime/openclaw/runAuth.js +7 -55
- package/dist/runtime/openclaw/statusProbes.d.ts +2 -0
- package/dist/runtime/openclaw/statusProbes.js +31 -0
- package/dist/runtime/picoclaw/adapter.js +10 -0
- package/dist/runtime/picoclaw/runAuth.d.ts +7 -0
- package/dist/runtime/picoclaw/runAuth.js +8 -68
- package/dist/runtime/picoclaw/statusProbes.d.ts +2 -0
- package/dist/runtime/picoclaw/statusProbes.js +100 -0
- package/dist/runtime/registry.d.ts +0 -5
- package/dist/runtime/registry.js +2 -12
- package/dist/runtime/statusProbes.d.ts +16 -0
- package/dist/runtime/statusProbes.js +41 -0
- package/dist/runtime/types.d.ts +52 -1
- package/dist/shared/errors.d.ts +6 -0
- package/dist/shared/errors.js +9 -0
- package/dist/status/buildStatus.d.ts +13 -0
- package/dist/status/buildStatus.js +266 -0
- package/dist/status/compileReport.d.ts +96 -0
- package/dist/status/compileReport.js +230 -0
- package/dist/status/compiledContainerObservations.d.ts +5 -0
- package/dist/status/compiledContainerObservations.js +63 -0
- package/dist/status/deploymentLogs.d.ts +12 -0
- package/dist/status/deploymentLogs.js +45 -0
- package/dist/status/deployments.d.ts +14 -0
- package/dist/status/deployments.js +128 -0
- package/dist/status/imageStatusReport.d.ts +10 -0
- package/dist/status/imageStatusReport.js +73 -0
- package/dist/status/index.d.ts +14 -0
- package/dist/status/index.js +14 -0
- package/dist/status/moltnetProbes.d.ts +21 -0
- package/dist/status/moltnetProbes.js +240 -0
- package/dist/status/registryDrift.d.ts +28 -0
- package/dist/status/registryDrift.js +119 -0
- package/dist/status/renderStatus.d.ts +2 -0
- package/dist/status/renderStatus.js +230 -0
- package/dist/status/runtimeProbes.d.ts +13 -0
- package/dist/status/runtimeProbes.js +111 -0
- package/dist/status/selectionSubjects.d.ts +8 -0
- package/dist/status/selectionSubjects.js +77 -0
- package/dist/status/selectors.d.ts +14 -0
- package/dist/status/selectors.js +90 -0
- package/dist/status/traversal.d.ts +6 -0
- package/dist/status/traversal.js +15 -0
- package/dist/status/types.d.ts +113 -0
- package/dist/status/types.js +1 -0
- package/package.json +4 -2
- package/runtimes.yaml +22 -15
- package/dist/runtime/tinyclaw/adapter.d.ts +0 -2
- package/dist/runtime/tinyclaw/adapter.js +0 -284
- package/dist/runtime/tinyclaw/runAuth.d.ts +0 -2
- package/dist/runtime/tinyclaw/runAuth.js +0 -49
- package/dist/runtime/tinyclaw/scaffold-assets/AGENTS.md +0 -160
- package/dist/runtime/tinyclaw/scaffold-assets/CLAUDE.md +0 -5
- package/dist/runtime/tinyclaw/scaffold-assets/SOUL.md +0 -177
- package/dist/runtime/tinyclaw/scaffold.d.ts +0 -2
- package/dist/runtime/tinyclaw/scaffold.js +0 -24
- package/dist/runtime/tinyclaw/schedules.d.ts +0 -9
- package/dist/runtime/tinyclaw/schedules.js +0 -62
- package/dist/runtime/tinyclaw/surfaces.d.ts +0 -8
- package/dist/runtime/tinyclaw/surfaces.js +0 -94
|
@@ -1,5 +1,106 @@
|
|
|
1
|
+
import { buildDistributionReport, createDistributionImageLabels, DISTRIBUTION_REPORT_OUTPUT_FILE, normalizeProjectLabelSlug } from "../distribution/index.js";
|
|
2
|
+
import { SpawnfileError } from "../shared/index.js";
|
|
1
3
|
import { createEnvVariableMap, createRuntimeTargetPlans } from "./containerArtifactsPlans.js";
|
|
2
4
|
import { createRootfsFiles, renderDockerfile, renderEntrypoint, renderEnvExample } from "./containerArtifactsRender.js";
|
|
5
|
+
const createOrganizationSummary = (plan, compiledNodes) => {
|
|
6
|
+
const nodes = compiledNodes.map((node) => ({
|
|
7
|
+
id: node.id ?? `${node.kind}:${node.slug}`,
|
|
8
|
+
kind: node.kind,
|
|
9
|
+
name: node.value.name,
|
|
10
|
+
runtimeName: node.runtimeName,
|
|
11
|
+
source: node.value.source
|
|
12
|
+
}));
|
|
13
|
+
const rootNode = nodes.find((node) => node.source === plan.root)
|
|
14
|
+
?? nodes.find((node) => !plan.edges.some((edge) => edge.to === node.id))
|
|
15
|
+
?? nodes[0];
|
|
16
|
+
if (!rootNode) {
|
|
17
|
+
throw new SpawnfileError("compile_error", `Unable to resolve the root node for ${plan.root}`);
|
|
18
|
+
}
|
|
19
|
+
const memberEdges = plan.edges.filter((edge) => edge.kind === "team_member");
|
|
20
|
+
const teamsByAgent = new Map();
|
|
21
|
+
for (const edge of memberEdges) {
|
|
22
|
+
teamsByAgent.set(edge.to, [...(teamsByAgent.get(edge.to) ?? []), edge.from]);
|
|
23
|
+
}
|
|
24
|
+
const agentNodes = nodes.filter((node) => node.kind === "agent");
|
|
25
|
+
const teamNodes = nodes.filter((node) => node.kind === "team");
|
|
26
|
+
const agentIds = new Set(agentNodes.map((node) => node.id));
|
|
27
|
+
return {
|
|
28
|
+
agents: agentNodes
|
|
29
|
+
.map((node) => ({
|
|
30
|
+
id: node.id,
|
|
31
|
+
name: node.name,
|
|
32
|
+
runtime: node.runtimeName,
|
|
33
|
+
teams: [...(teamsByAgent.get(node.id) ?? [])].sort()
|
|
34
|
+
}))
|
|
35
|
+
.sort((left, right) => left.id.localeCompare(right.id)),
|
|
36
|
+
project: rootNode.name,
|
|
37
|
+
teams: teamNodes
|
|
38
|
+
.map((node) => ({
|
|
39
|
+
agents: memberEdges
|
|
40
|
+
.filter((edge) => edge.from === node.id && agentIds.has(edge.to))
|
|
41
|
+
.map((edge) => edge.to)
|
|
42
|
+
.sort(),
|
|
43
|
+
id: node.id,
|
|
44
|
+
name: node.name
|
|
45
|
+
}))
|
|
46
|
+
.sort((left, right) => left.id.localeCompare(right.id))
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const resolveMoltnetOperatorTokenSecret = (plan) => {
|
|
50
|
+
const client = plan.server.auth.client;
|
|
51
|
+
if (!client) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
if (client.token_env) {
|
|
55
|
+
return client.token_env;
|
|
56
|
+
}
|
|
57
|
+
if (client.token_path) {
|
|
58
|
+
return client.token_path;
|
|
59
|
+
}
|
|
60
|
+
if (!client.token_id) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
return plan.server.auth.tokens?.find((token) => token.id === client.token_id)?.secret;
|
|
64
|
+
};
|
|
65
|
+
const createMoltnetSummary = (moltnet) => {
|
|
66
|
+
if (!moltnet) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
node_plans: moltnet.nodePlans.map((plan) => ({
|
|
71
|
+
config_path: plan.configPath,
|
|
72
|
+
network_id: plan.networkId
|
|
73
|
+
})),
|
|
74
|
+
server_plans: moltnet.serverPlans.map((plan) => {
|
|
75
|
+
const operatorTokenSecret = resolveMoltnetOperatorTokenSecret(plan);
|
|
76
|
+
return {
|
|
77
|
+
auth_mode: plan.server.auth.mode,
|
|
78
|
+
base_url: plan.baseUrl,
|
|
79
|
+
...(plan.configPath ? { config_path: plan.configPath } : {}),
|
|
80
|
+
...(plan.server.mode === "managed"
|
|
81
|
+
? { direct_messages: plan.server.direct_messages }
|
|
82
|
+
: {}),
|
|
83
|
+
id: plan.id,
|
|
84
|
+
mode: plan.mode,
|
|
85
|
+
network_id: plan.networkId,
|
|
86
|
+
...(operatorTokenSecret ? { operator_token_secret: operatorTokenSecret } : {}),
|
|
87
|
+
...(plan.port ? { port: plan.port } : {}),
|
|
88
|
+
...(plan.server.auth.public_read !== undefined
|
|
89
|
+
? { public_read: plan.server.auth.public_read }
|
|
90
|
+
: {}),
|
|
91
|
+
rooms: plan.rooms.map((room) => ({
|
|
92
|
+
id: room.id,
|
|
93
|
+
members: [...room.members],
|
|
94
|
+
...(room.visibility ? { visibility: room.visibility } : {}),
|
|
95
|
+
...(room.write_policy ? { write_policy: room.write_policy } : {})
|
|
96
|
+
})),
|
|
97
|
+
...(plan.server.mode === "managed"
|
|
98
|
+
? { store_kind: plan.server.store.kind }
|
|
99
|
+
: {})
|
|
100
|
+
};
|
|
101
|
+
})
|
|
102
|
+
};
|
|
103
|
+
};
|
|
3
104
|
export const createContainerArtifacts = async (plan, compiledNodes, options = {}) => {
|
|
4
105
|
const runtimePlans = await createRuntimeTargetPlans(plan, compiledNodes);
|
|
5
106
|
const envVariables = [...createEnvVariableMap(compiledNodes, runtimePlans).values()].sort((left, right) => left.name.localeCompare(right.name));
|
|
@@ -23,11 +124,108 @@ export const createContainerArtifacts = async (plan, compiledNodes, options = {}
|
|
|
23
124
|
volume_name: mount.volumeName
|
|
24
125
|
}))
|
|
25
126
|
.sort((left, right) => left.id.localeCompare(right.id));
|
|
127
|
+
const runtimeInternalPorts = runtimePlans.flatMap((plan) => plan.port ? [plan.port] : []);
|
|
128
|
+
const internalPorts = [...new Set([...runtimeInternalPorts, ...(options.moltnet?.ports ?? [])])].sort((left, right) => left - right);
|
|
129
|
+
const runtimePublishedPorts = runtimePlans.flatMap((plan) => plan.publishedPort ? [plan.publishedPort] : []);
|
|
130
|
+
const publishedPorts = [
|
|
131
|
+
...new Set([...runtimePublishedPorts, ...(options.moltnet?.publishedPorts ?? [])])
|
|
132
|
+
].sort((left, right) => left - right);
|
|
133
|
+
const portMappings = runtimePlans
|
|
134
|
+
.flatMap((plan) => plan.port && plan.publishedPort
|
|
135
|
+
? [{ internal_port: plan.port, published_port: plan.publishedPort }]
|
|
136
|
+
: [])
|
|
137
|
+
.sort((left, right) => left.published_port - right.published_port
|
|
138
|
+
|| left.internal_port - right.internal_port);
|
|
139
|
+
const runtimeHomes = [
|
|
140
|
+
...new Set(runtimePlans.flatMap((plan) => (plan.instancePaths.homePath ? [plan.instancePaths.homePath] : [])))
|
|
141
|
+
].sort();
|
|
142
|
+
const runtimeInstances = runtimePlans
|
|
143
|
+
.map((plan) => ({
|
|
144
|
+
config_path: plan.instancePaths.configPath,
|
|
145
|
+
home_path: plan.instancePaths.homePath ?? null,
|
|
146
|
+
id: plan.id,
|
|
147
|
+
internal_port: plan.port ?? null,
|
|
148
|
+
model_auth_methods: plan.modelAuthMethods,
|
|
149
|
+
model_secrets_required: plan.modelSecretsRequired,
|
|
150
|
+
node_ids: [...(plan.sourceIds ?? [])],
|
|
151
|
+
published_port: plan.publishedPort ?? null,
|
|
152
|
+
runtime: plan.runtimeName,
|
|
153
|
+
workspace_path: plan.instancePaths.workspacePath
|
|
154
|
+
}))
|
|
155
|
+
.sort((left, right) => left.id.localeCompare(right.id));
|
|
156
|
+
const runtimesInstalled = [...new Set(runtimePlans.map((plan) => plan.runtimeName))].sort();
|
|
157
|
+
const workspaceResources = [
|
|
158
|
+
...new Map(runtimePlans.flatMap((plan) => (plan.resources ?? []).map((resource) => [
|
|
159
|
+
`${resource.kind}:${resource.id}:${resource.linkPath}`,
|
|
160
|
+
{
|
|
161
|
+
backing_path: resource.backingPath,
|
|
162
|
+
id: resource.id,
|
|
163
|
+
kind: resource.kind,
|
|
164
|
+
link_path: resource.linkPath,
|
|
165
|
+
mode: resource.mode,
|
|
166
|
+
mount: resource.mount,
|
|
167
|
+
sharing: resource.sharing
|
|
168
|
+
}
|
|
169
|
+
]))).values()
|
|
170
|
+
].sort((left, right) => left.link_path.localeCompare(right.link_path) || left.id.localeCompare(right.id));
|
|
171
|
+
const moltnetSummary = createMoltnetSummary(options.moltnet);
|
|
172
|
+
const organization = createOrganizationSummary(plan, compiledNodes);
|
|
173
|
+
const projectSlug = normalizeProjectLabelSlug(organization.project);
|
|
174
|
+
const mergedModelAuthMethods = Object.assign({}, ...runtimePlans.map((runtimePlan) => runtimePlan.modelAuthMethods));
|
|
175
|
+
const moltnetNetworks = [
|
|
176
|
+
...new Map((options.moltnet?.serverPlans ?? []).map((serverPlan) => [
|
|
177
|
+
serverPlan.networkId,
|
|
178
|
+
{
|
|
179
|
+
binding: "env",
|
|
180
|
+
id: serverPlan.networkId,
|
|
181
|
+
server_mode: serverPlan.mode
|
|
182
|
+
}
|
|
183
|
+
])).values()
|
|
184
|
+
];
|
|
185
|
+
const distributionReport = buildDistributionReport({
|
|
186
|
+
envVariables: envVariables.map((variable) => ({
|
|
187
|
+
categories: variable.categories,
|
|
188
|
+
generated: variable.generated,
|
|
189
|
+
name: variable.name,
|
|
190
|
+
required: variable.required
|
|
191
|
+
})),
|
|
192
|
+
generatedAt: options.generatedAt ?? new Date().toISOString(),
|
|
193
|
+
internalPorts,
|
|
194
|
+
modelAuthMethods: mergedModelAuthMethods,
|
|
195
|
+
moltnetNetworks,
|
|
196
|
+
organization,
|
|
197
|
+
persistentMounts: persistentMounts.map((mount) => ({
|
|
198
|
+
durability: "persistent",
|
|
199
|
+
id: mount.id,
|
|
200
|
+
kind: "volume",
|
|
201
|
+
target: mount.mount_path
|
|
202
|
+
})),
|
|
203
|
+
portMappings,
|
|
204
|
+
publishedPorts,
|
|
205
|
+
resources: workspaceResources.map((resource) => ({
|
|
206
|
+
id: resource.id,
|
|
207
|
+
kind: resource.kind,
|
|
208
|
+
link_path: resource.link_path,
|
|
209
|
+
mode: resource.mode,
|
|
210
|
+
mount: resource.mount,
|
|
211
|
+
sharing: resource.sharing
|
|
212
|
+
})),
|
|
213
|
+
runtimeInstances
|
|
214
|
+
});
|
|
215
|
+
const distributionLabels = createDistributionImageLabels(projectSlug, distributionReport.compile_fingerprint);
|
|
26
216
|
const files = [
|
|
27
217
|
...createRootfsFiles(runtimePlans),
|
|
28
218
|
...(options.moltnet?.files ?? []),
|
|
219
|
+
{
|
|
220
|
+
content: `${JSON.stringify(distributionReport, null, 2)}\n`,
|
|
221
|
+
path: DISTRIBUTION_REPORT_OUTPUT_FILE
|
|
222
|
+
},
|
|
29
223
|
{
|
|
30
224
|
content: await renderDockerfile(runtimePlans, {
|
|
225
|
+
distribution: {
|
|
226
|
+
labels: distributionLabels,
|
|
227
|
+
reportOutputFile: DISTRIBUTION_REPORT_OUTPUT_FILE
|
|
228
|
+
},
|
|
31
229
|
hasMoltnet: Boolean(options.moltnet),
|
|
32
230
|
hasStagedMoltnetBinaries: options.hasStagedMoltnetBinaries,
|
|
33
231
|
moltnetPublishedPorts: options.moltnet?.publishedPorts ?? [],
|
|
@@ -51,38 +249,12 @@ export const createContainerArtifacts = async (plan, compiledNodes, options = {}
|
|
|
51
249
|
path: ".env.example"
|
|
52
250
|
}
|
|
53
251
|
];
|
|
54
|
-
const runtimePorts = runtimePlans.flatMap((plan) => plan.publishedPort ? [plan.publishedPort] : []);
|
|
55
|
-
const moltnetPorts = options.moltnet?.publishedPorts ?? [];
|
|
56
|
-
const ports = [...new Set([...runtimePorts, ...moltnetPorts])].sort((left, right) => left - right);
|
|
57
|
-
const runtimeHomes = [
|
|
58
|
-
...new Set(runtimePlans.flatMap((plan) => (plan.instancePaths.homePath ? [plan.instancePaths.homePath] : [])))
|
|
59
|
-
].sort();
|
|
60
|
-
const runtimeInstances = runtimePlans
|
|
61
|
-
.map((plan) => ({
|
|
62
|
-
config_path: plan.instancePaths.configPath,
|
|
63
|
-
home_path: plan.instancePaths.homePath ?? null,
|
|
64
|
-
id: plan.id,
|
|
65
|
-
model_auth_methods: plan.modelAuthMethods,
|
|
66
|
-
model_secrets_required: plan.modelSecretsRequired,
|
|
67
|
-
runtime: plan.runtimeName
|
|
68
|
-
}))
|
|
69
|
-
.sort((left, right) => left.id.localeCompare(right.id));
|
|
70
|
-
const runtimesInstalled = [...new Set(runtimePlans.map((plan) => plan.runtimeName))].sort();
|
|
71
|
-
const workspaceResources = [
|
|
72
|
-
...new Map(runtimePlans.flatMap((plan) => (plan.resources ?? []).map((resource) => [
|
|
73
|
-
`${resource.kind}:${resource.id}:${resource.linkPath}`,
|
|
74
|
-
{
|
|
75
|
-
backing_path: resource.backingPath,
|
|
76
|
-
id: resource.id,
|
|
77
|
-
kind: resource.kind,
|
|
78
|
-
link_path: resource.linkPath,
|
|
79
|
-
mode: resource.mode,
|
|
80
|
-
mount: resource.mount,
|
|
81
|
-
sharing: resource.sharing
|
|
82
|
-
}
|
|
83
|
-
]))).values()
|
|
84
|
-
].sort((left, right) => left.link_path.localeCompare(right.link_path) || left.id.localeCompare(right.id));
|
|
85
252
|
return {
|
|
253
|
+
distribution: {
|
|
254
|
+
fingerprint: distributionReport.compile_fingerprint,
|
|
255
|
+
labels: distributionLabels,
|
|
256
|
+
report: distributionReport
|
|
257
|
+
},
|
|
86
258
|
executablePaths: ["entrypoint.sh"],
|
|
87
259
|
files,
|
|
88
260
|
...(options.moltnet
|
|
@@ -97,8 +269,12 @@ export const createContainerArtifacts = async (plan, compiledNodes, options = {}
|
|
|
97
269
|
dockerfile: "Dockerfile",
|
|
98
270
|
entrypoint: "entrypoint.sh",
|
|
99
271
|
env_example: ".env.example",
|
|
272
|
+
internal_ports: internalPorts,
|
|
100
273
|
model_secrets_required: modelSecretsRequired,
|
|
101
|
-
|
|
274
|
+
...(moltnetSummary ? { moltnet: moltnetSummary } : {}),
|
|
275
|
+
port_mappings: portMappings,
|
|
276
|
+
ports: publishedPorts,
|
|
277
|
+
published_ports: publishedPorts,
|
|
102
278
|
runtime_instances: runtimeInstances,
|
|
103
279
|
runtime_homes: runtimeHomes,
|
|
104
280
|
runtime_secrets_required: runtimeSecretsRequired,
|
|
@@ -65,12 +65,13 @@ const resolveInstancePaths = (runtimeName, targetId, meta) => {
|
|
|
65
65
|
};
|
|
66
66
|
export const createEnvVariableMap = (compiledNodes, runtimePlans) => {
|
|
67
67
|
const variables = new Map();
|
|
68
|
-
const register = (name, required, description, category) => {
|
|
68
|
+
const register = (name, required, description, category, generated = false) => {
|
|
69
69
|
const current = variables.get(name);
|
|
70
70
|
if (!current) {
|
|
71
71
|
variables.set(name, {
|
|
72
72
|
categories: [category],
|
|
73
73
|
description,
|
|
74
|
+
generated,
|
|
74
75
|
name,
|
|
75
76
|
required
|
|
76
77
|
});
|
|
@@ -79,6 +80,7 @@ export const createEnvVariableMap = (compiledNodes, runtimePlans) => {
|
|
|
79
80
|
variables.set(name, {
|
|
80
81
|
...current,
|
|
81
82
|
categories: [...new Set([...current.categories, category])],
|
|
83
|
+
generated: current.generated && generated,
|
|
82
84
|
required: current.required || required
|
|
83
85
|
});
|
|
84
86
|
};
|
|
@@ -104,10 +106,10 @@ export const createEnvVariableMap = (compiledNodes, runtimePlans) => {
|
|
|
104
106
|
}
|
|
105
107
|
for (const runtimePlan of runtimePlans) {
|
|
106
108
|
for (const variable of runtimePlan.meta.env ?? []) {
|
|
107
|
-
register(variable.name, variable.required, variable.description, "runtime");
|
|
109
|
+
register(variable.name, variable.required, variable.description, "runtime", variable.generated ?? false);
|
|
108
110
|
}
|
|
109
111
|
for (const binding of runtimePlan.targetConfigEnvBindings ?? []) {
|
|
110
|
-
register(binding.envName, true, `Injected into ${runtimePlan.runtimeName} runtime config`, "runtime");
|
|
112
|
+
register(binding.envName, true, `Injected into ${runtimePlan.runtimeName} runtime config`, "runtime", binding.generated ?? false);
|
|
111
113
|
}
|
|
112
114
|
}
|
|
113
115
|
return variables;
|
|
@@ -165,7 +167,7 @@ export const createRuntimeTargetPlans = async (plan, compiledNodes) => {
|
|
|
165
167
|
.filter((node) => node.runtimeName === runtimeName && node.emittedFiles.length > 0)
|
|
166
168
|
.map((node) => ({
|
|
167
169
|
emittedFiles: node.emittedFiles,
|
|
168
|
-
id: `${node.kind}:${node.slug}`,
|
|
170
|
+
id: node.id ?? `${node.kind}:${node.slug}`,
|
|
169
171
|
kind: node.kind,
|
|
170
172
|
slug: node.slug,
|
|
171
173
|
value: node.value
|
|
@@ -192,6 +194,7 @@ export const createRuntimeTargetPlans = async (plan, compiledNodes) => {
|
|
|
192
194
|
resources: resolveTargetResources(target, targetInputs, instancePaths, adapter.container),
|
|
193
195
|
runtimeName,
|
|
194
196
|
runtimeRoot: recipe.runtimeRoot,
|
|
197
|
+
sourceIds: [...(target.sourceIds ?? [])].sort(),
|
|
195
198
|
targetConfigEnvBindings: target.configEnvBindings,
|
|
196
199
|
targetFiles: target.files
|
|
197
200
|
});
|
|
@@ -4,5 +4,11 @@ import type { EntrypointOptions } from "./containerEntrypointRender.js";
|
|
|
4
4
|
export { renderEntrypoint } from "./containerEntrypointRender.js";
|
|
5
5
|
export type { EntrypointOptions } from "./containerEntrypointRender.js";
|
|
6
6
|
export declare const renderEnvExample: (variables: ContainerEnvVariable[]) => string;
|
|
7
|
-
export
|
|
7
|
+
export interface DockerfileDistributionOptions {
|
|
8
|
+
labels: Record<string, string>;
|
|
9
|
+
reportOutputFile: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const renderDockerfile: (runtimePlans: RuntimeTargetPlan[], options?: EntrypointOptions & {
|
|
12
|
+
distribution?: DockerfileDistributionOptions;
|
|
13
|
+
}) => Promise<string>;
|
|
8
14
|
export declare const createRootfsFiles: (runtimePlans: RuntimeTargetPlan[]) => EmittedFile[];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { DISTRIBUTION_REPORT_IMAGE_PATH } from "../distribution/index.js";
|
|
2
3
|
import { createRuntimeInstallRecipe } from "../runtime/index.js";
|
|
3
4
|
import { SpawnfileError } from "../shared/index.js";
|
|
4
5
|
export { renderEntrypoint } from "./containerEntrypointRender.js";
|
|
@@ -194,6 +195,11 @@ export const renderDockerfile = async (runtimePlans, options = {}) => {
|
|
|
194
195
|
}
|
|
195
196
|
lines.push('RUN if ! id -u spawnfile >/dev/null 2>&1; then useradd --create-home --home-dir /home/spawnfile --shell /bin/bash spawnfile; fi', "");
|
|
196
197
|
lines.push("COPY container/rootfs/ /", "COPY .env.example /opt/spawnfile/.env.example", 'COPY entrypoint.sh /opt/spawnfile/entrypoint.sh', "RUN chmod +x /opt/spawnfile/entrypoint.sh");
|
|
198
|
+
if (options.distribution) {
|
|
199
|
+
lines.push("", `COPY ${options.distribution.reportOutputFile} ${DISTRIBUTION_REPORT_IMAGE_PATH}`, ...Object.entries(options.distribution.labels)
|
|
200
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
201
|
+
.map(([name, value]) => `LABEL ${name}=${shellQuote(value)}`));
|
|
202
|
+
}
|
|
197
203
|
lines.push(`RUN ${createStateOwnershipCommand(options.persistentMountPaths)}`);
|
|
198
204
|
if (exposedPorts.length > 0) {
|
|
199
205
|
lines.push(`EXPOSE ${exposedPorts.join(" ")}`);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DistributionReport } from "../distribution/index.js";
|
|
1
2
|
import type { ContainerReport } from "../report/index.js";
|
|
2
3
|
import type { EmittedFile, RuntimeContainerConfigEnvBinding, RuntimeContainerMeta } from "../runtime/index.js";
|
|
3
4
|
import type { ModelAuthMethod } from "../shared/index.js";
|
|
@@ -7,6 +8,7 @@ import type { WorkspaceResourcePlan } from "./workspaceResources.js";
|
|
|
7
8
|
export interface ContainerEnvVariable {
|
|
8
9
|
categories: Array<"model" | "project" | "runtime" | "surface">;
|
|
9
10
|
description: string;
|
|
11
|
+
generated: boolean;
|
|
10
12
|
name: string;
|
|
11
13
|
required: boolean;
|
|
12
14
|
}
|
|
@@ -32,17 +34,24 @@ export interface RuntimeTargetPlan {
|
|
|
32
34
|
resources?: WorkspaceResourcePlan[];
|
|
33
35
|
runtimeName: string;
|
|
34
36
|
runtimeRoot: string;
|
|
37
|
+
sourceIds?: string[];
|
|
35
38
|
targetConfigEnvBindings?: RuntimeContainerConfigEnvBinding[];
|
|
36
39
|
targetFiles: EmittedFile[];
|
|
37
40
|
}
|
|
38
41
|
export interface CompiledNodeArtifact {
|
|
39
42
|
emittedFiles: EmittedFile[];
|
|
43
|
+
id?: string;
|
|
40
44
|
kind: "agent" | "team";
|
|
41
45
|
runtimeName: string | null;
|
|
42
46
|
slug: string;
|
|
43
47
|
value: ResolvedAgentNode | ResolvedTeamNode;
|
|
44
48
|
}
|
|
45
49
|
export interface GeneratedContainerArtifacts {
|
|
50
|
+
distribution: {
|
|
51
|
+
fingerprint: string;
|
|
52
|
+
labels: Record<string, string>;
|
|
53
|
+
report: DistributionReport;
|
|
54
|
+
};
|
|
46
55
|
executablePaths: string[];
|
|
47
56
|
files: EmittedFile[];
|
|
48
57
|
moltnet?: {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { resolveMoltnetStorePath } from "./moltnetConfigLowering.js";
|
|
3
|
+
import { networkUrlEnvName } from "./networkBinding.js";
|
|
3
4
|
import { createWorkspaceResourceCommands, createWorkspaceResourceShellFunctions } from "./containerWorkspaceResourceRender.js";
|
|
4
5
|
const MOLTNET_SERVER_DATA_DIRECTORY = "/var/lib/spawnfile/moltnet/servers";
|
|
5
6
|
const shellQuote = (value) => `'${value.replace(/'/g, `'\"'\"'`)}'`;
|
|
@@ -8,9 +9,9 @@ const createEnvironmentAssignments = (plan) => {
|
|
|
8
9
|
if (plan.instancePaths.homePath) {
|
|
9
10
|
envAssignments.push(`HOME=${shellQuote(plan.instancePaths.homePath)}`);
|
|
10
11
|
}
|
|
11
|
-
if (plan.instancePaths.homePath &&
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
if (plan.instancePaths.homePath &&
|
|
13
|
+
plan.runtimeName === "picoclaw" &&
|
|
14
|
+
plan.modelAuthMethods.openai === "codex") {
|
|
14
15
|
envAssignments.push(`CODEX_HOME=${shellQuote(path.posix.join(plan.instancePaths.homePath, ".codex"))}`);
|
|
15
16
|
}
|
|
16
17
|
if (plan.meta.homeEnv && plan.instancePaths.homePath) {
|
|
@@ -29,14 +30,6 @@ const createEnvironmentAssignments = (plan) => {
|
|
|
29
30
|
};
|
|
30
31
|
const createEnvFileWrites = (plan) => plan.envFiles.map((binding) => `write_env_file ${shellQuote(binding.envName)} ${shellQuote(binding.filePath)}`);
|
|
31
32
|
const createConfigEnvWrites = (plan) => (plan.configEnvBindings ?? []).map((binding) => `apply_json_env_value ${shellQuote(plan.instancePaths.configPath)} ${shellQuote(binding.envName)} ${shellQuote(binding.jsonPath)}`);
|
|
32
|
-
const createAuthSetupCommands = (plan) => {
|
|
33
|
-
if (plan.runtimeName !== "tinyclaw" ||
|
|
34
|
-
!plan.instancePaths.homePath ||
|
|
35
|
-
plan.modelAuthMethods.openai !== "api_key") {
|
|
36
|
-
return [];
|
|
37
|
-
}
|
|
38
|
-
return [`configure_codex_api_key_auth ${shellQuote(plan.instancePaths.homePath)}`];
|
|
39
|
-
};
|
|
40
33
|
const createMoltnetStorePrepareCommands = (serverPlan) => {
|
|
41
34
|
const server = serverPlan.server;
|
|
42
35
|
if (server.mode !== "managed" || server.store.kind === "memory" || server.store.kind === "postgres") {
|
|
@@ -145,15 +138,6 @@ export const renderEntrypoint = (runtimePlans, requiredSecrets, options = {}) =>
|
|
|
145
138
|
"PY",
|
|
146
139
|
"}",
|
|
147
140
|
"",
|
|
148
|
-
"configure_codex_api_key_auth() {",
|
|
149
|
-
' local home_path="$1"',
|
|
150
|
-
' if [ -z "${OPENAI_API_KEY:-}" ]; then',
|
|
151
|
-
" return",
|
|
152
|
-
" fi",
|
|
153
|
-
' mkdir -p "$home_path/.codex"',
|
|
154
|
-
' printf "%s\\n" "${OPENAI_API_KEY:-}" | HOME="$home_path" CODEX_HOME="$home_path/.codex" codex login --with-api-key >/dev/null',
|
|
155
|
-
"}",
|
|
156
|
-
"",
|
|
157
141
|
...createWorkspaceResourceShellFunctions()
|
|
158
142
|
];
|
|
159
143
|
lines.push('if [ -n "${OPENCLAW_GATEWAY_TOKEN:-}" ] && [ -z "${OPENCLAW_HOOKS_TOKEN:-}" ]; then', ' export OPENCLAW_HOOKS_TOKEN="hooks-${OPENCLAW_GATEWAY_TOKEN}"', "fi", "");
|
|
@@ -171,7 +155,7 @@ export const renderEntrypoint = (runtimePlans, requiredSecrets, options = {}) =>
|
|
|
171
155
|
const plan = runtimePlans[0];
|
|
172
156
|
const commandTokens = resolveStartCommand(plan);
|
|
173
157
|
const envAssignments = createEnvironmentAssignments(plan);
|
|
174
|
-
lines.push(`mkdir -p ${shellQuote(plan.instancePaths.workspacePath)}`, ...createWorkspaceResourceCommands(plan), `require_file ${shellQuote(plan.instancePaths.configPath)}`, ...createEnvFileWrites(plan), ...createConfigEnvWrites(plan),
|
|
158
|
+
lines.push(`mkdir -p ${shellQuote(plan.instancePaths.workspacePath)}`, ...createWorkspaceResourceCommands(plan), `require_file ${shellQuote(plan.instancePaths.configPath)}`, ...createEnvFileWrites(plan), ...createConfigEnvWrites(plan), `${envAssignments.join(" ")} exec ${commandTokens.map(shellQuote).join(" ")}`);
|
|
175
159
|
return `${lines.join("\n").trimEnd()}\n`;
|
|
176
160
|
}
|
|
177
161
|
lines.push("PIDS=()", "", "terminate_children() {", ' for pid in "${PIDS[@]:-}"; do', ' kill "$pid" 2>/dev/null || true', " done", "}", "", "trap terminate_children INT TERM EXIT", "");
|
|
@@ -183,25 +167,28 @@ export const renderEntrypoint = (runtimePlans, requiredSecrets, options = {}) =>
|
|
|
183
167
|
if (!serverPlan.configPath) {
|
|
184
168
|
continue;
|
|
185
169
|
}
|
|
170
|
+
const urlEnv = networkUrlEnvName(serverPlan.networkId);
|
|
171
|
+
const serverLines = [];
|
|
186
172
|
for (const patch of serverPlan.secretPatches) {
|
|
187
|
-
|
|
173
|
+
serverLines.push(`apply_json_env_value ${shellQuote(serverPlan.configPath)} ${shellQuote(patch.envName)} ${shellQuote(patch.jsonPath)}`);
|
|
188
174
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if (!serverPlan.port) {
|
|
193
|
-
continue;
|
|
175
|
+
serverLines.push(...createMoltnetStorePrepareCommands(serverPlan), `MOLTNET_CONFIG=${shellQuote(serverPlan.configPath)} /usr/local/bin/moltnet &`, 'PIDS+=("$!")');
|
|
176
|
+
if (serverPlan.port) {
|
|
177
|
+
serverLines.push(`until curl -sf ${shellQuote(`http://127.0.0.1:${serverPlan.port}/healthz`)} >/dev/null; do sleep 1; done`);
|
|
194
178
|
}
|
|
195
|
-
|
|
196
|
-
lines.push("");
|
|
179
|
+
// Suppress the in-image managed server when an external endpoint is bound.
|
|
180
|
+
lines.push(`if [ -z "\${${urlEnv}:-}" ]; then`, ...serverLines.map((line) => ` ${line}`), "fi", "");
|
|
197
181
|
}
|
|
198
182
|
for (const plan of runtimePlans) {
|
|
199
183
|
const commandTokens = resolveStartCommand(plan);
|
|
200
184
|
const envAssignments = createEnvironmentAssignments(plan);
|
|
201
|
-
lines.push(`mkdir -p ${shellQuote(plan.instancePaths.workspacePath)}`, ...createWorkspaceResourceCommands(plan), `require_file ${shellQuote(plan.instancePaths.configPath)}`, ...createEnvFileWrites(plan), ...createConfigEnvWrites(plan),
|
|
185
|
+
lines.push(`mkdir -p ${shellQuote(plan.instancePaths.workspacePath)}`, ...createWorkspaceResourceCommands(plan), `require_file ${shellQuote(plan.instancePaths.configPath)}`, ...createEnvFileWrites(plan), ...createConfigEnvWrites(plan), `${envAssignments.join(" ")} ${commandTokens.map(shellQuote).join(" ")} &`, 'PIDS+=("$!")', "", ...createRuntimeReadinessWait(plan));
|
|
202
186
|
}
|
|
203
187
|
for (const nodePlan of moltnetNodePlans) {
|
|
204
|
-
|
|
188
|
+
const urlEnv = networkUrlEnvName(nodePlan.networkId);
|
|
189
|
+
lines.push(
|
|
190
|
+
// Rebind the bridge endpoint when an external network URL is provided.
|
|
191
|
+
`if [ -n "\${${urlEnv}:-}" ]; then`, ` apply_json_env_value ${shellQuote(nodePlan.configPath)} ${shellQuote(urlEnv)} ${shellQuote("moltnet.base_url")}`, "fi", `/usr/local/bin/moltnet node ${shellQuote(nodePlan.configPath)} &`, 'PIDS+=("$!")', "");
|
|
205
192
|
}
|
|
206
193
|
lines.push('if [ "${#PIDS[@]}" -eq 0 ]; then', ' echo "No runtime targets were generated for this compile output" >&2', " exit 1", "fi", "", "status=0", 'for pid in "${PIDS[@]}"; do', ' if ! wait "$pid"; then', " status=1", " fi", "done", "", 'exit "$status"');
|
|
207
194
|
return `${lines.join("\n").trimEnd()}\n`;
|
package/dist/compiler/index.d.ts
CHANGED
package/dist/compiler/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SpawnfileError } from "../shared/index.js";
|
|
2
2
|
import { createMoltnetOpenTokenDirectory, createMoltnetNativeServerConfig, createMoltnetNodeConfigPath, createMoltnetServerConfigPath, resolveMoltnetBaseUrl, resolveMoltnetStorePersistenceMountPath } from "./moltnetConfigLowering.js";
|
|
3
|
+
import { assertNetworkBindingEnvUniqueness } from "./networkBinding.js";
|
|
3
4
|
import { listConcreteMoltnetRoomMemberIds } from "./moltnetRoomMemberships.js";
|
|
4
5
|
import { assertCompatibleMoltnetNetworkName, assertCompatibleMoltnetRoomPolicy, assertCompatibleMoltnetServer } from "./moltnetRoomPolicyCompatibility.js";
|
|
5
6
|
import { createMoltnetNodeConfigContent } from "./moltnetNodeConfig.js";
|
|
@@ -207,6 +208,10 @@ export const generateMoltnetArtifacts = async (plan) => {
|
|
|
207
208
|
}
|
|
208
209
|
}
|
|
209
210
|
const managedServerPlans = [...serverPlans.values()].filter((serverPlan) => serverPlan.mode === "managed");
|
|
211
|
+
assertNetworkBindingEnvUniqueness([...serverPlans.values()].map((serverPlan) => ({
|
|
212
|
+
id: serverPlan.networkId,
|
|
213
|
+
members: [...new Set(serverPlan.rooms.flatMap((room) => room.members))]
|
|
214
|
+
})));
|
|
210
215
|
return {
|
|
211
216
|
files: configFiles,
|
|
212
217
|
nodePlans: nodePlans.sort((left, right) => left.configPath.localeCompare(right.configPath)),
|
|
@@ -7,5 +7,5 @@ export interface MoltnetWorkspaceLayout {
|
|
|
7
7
|
skillPaths: string[];
|
|
8
8
|
workspaceRootPath: string;
|
|
9
9
|
}
|
|
10
|
-
export declare const resolveMoltnetWorkspaceLayout: (runtimeName: string,
|
|
10
|
+
export declare const resolveMoltnetWorkspaceLayout: (runtimeName: string, _agentName: string) => MoltnetWorkspaceLayout;
|
|
11
11
|
export declare const createMoltnetClientConfigFiles: (node: ResolvedAgentNode, artifacts: MoltnetArtifacts, agentSlug?: string) => EmittedFile[];
|
|
@@ -38,8 +38,7 @@ const createAttachmentConfig = (node, artifacts, attachment, agentSlug) => {
|
|
|
38
38
|
? {
|
|
39
39
|
dms: {
|
|
40
40
|
enabled: attachment.dms.enabled,
|
|
41
|
-
...(attachment.dms.
|
|
42
|
-
...(attachment.dms.reply ? { reply: attachment.dms.reply } : {})
|
|
41
|
+
...(attachment.dms.wake ? { wake: attachment.dms.wake } : {})
|
|
43
42
|
}
|
|
44
43
|
}
|
|
45
44
|
: {}),
|
|
@@ -56,15 +55,14 @@ const createAttachmentConfig = (node, artifacts, attachment, agentSlug) => {
|
|
|
56
55
|
id: roomId,
|
|
57
56
|
...(room?.visibility ? { visibility: room.visibility } : {}),
|
|
58
57
|
...(room?.write_policy ? { write_policy: room.write_policy } : {}),
|
|
59
|
-
...(policy.
|
|
60
|
-
...(policy.reply ? { reply: policy.reply } : {})
|
|
58
|
+
...(policy.wake ? { wake: policy.wake } : {})
|
|
61
59
|
};
|
|
62
60
|
})
|
|
63
61
|
}
|
|
64
62
|
: {})
|
|
65
63
|
};
|
|
66
64
|
};
|
|
67
|
-
export const resolveMoltnetWorkspaceLayout = (runtimeName,
|
|
65
|
+
export const resolveMoltnetWorkspaceLayout = (runtimeName, _agentName) => {
|
|
68
66
|
if (runtimeName === "openclaw" || runtimeName === "picoclaw") {
|
|
69
67
|
return {
|
|
70
68
|
clientConfigPath: `workspace/${GENERATED_CONFIG_PATH}`,
|
|
@@ -73,17 +71,6 @@ export const resolveMoltnetWorkspaceLayout = (runtimeName, agentName) => {
|
|
|
73
71
|
workspaceRootPath: "workspace"
|
|
74
72
|
};
|
|
75
73
|
}
|
|
76
|
-
if (runtimeName === "tinyclaw") {
|
|
77
|
-
return {
|
|
78
|
-
clientConfigPath: `workspace/${agentName}/${GENERATED_CONFIG_PATH}`,
|
|
79
|
-
cliRuntime: runtimeName,
|
|
80
|
-
skillPaths: [
|
|
81
|
-
`workspace/${agentName}/.agents/skills/${GENERATED_SKILL_NAME}/SKILL.md`,
|
|
82
|
-
`workspace/${agentName}/.claude/skills/${GENERATED_SKILL_NAME}/SKILL.md`
|
|
83
|
-
],
|
|
84
|
-
workspaceRootPath: `workspace/${agentName}`
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
74
|
throw new SpawnfileError("compile_error", `Moltnet client config does not know how to emit files for runtime ${runtimeName}`);
|
|
88
75
|
};
|
|
89
76
|
export const createMoltnetClientConfigFiles = (node, artifacts, agentSlug) => {
|
|
@@ -47,8 +47,7 @@ export const createMoltnetNodeConfigContent = ({ agentNode, attachment, networkS
|
|
|
47
47
|
id: roomId,
|
|
48
48
|
...(room?.visibility ? { visibility: room.visibility } : {}),
|
|
49
49
|
...(room?.write_policy ? { write_policy: room.write_policy } : {}),
|
|
50
|
-
...(policy.
|
|
51
|
-
...(policy.reply ? { reply: policy.reply } : {})
|
|
50
|
+
...(policy.wake ? { wake: policy.wake } : {})
|
|
52
51
|
};
|
|
53
52
|
})
|
|
54
53
|
}
|
|
@@ -57,8 +56,7 @@ export const createMoltnetNodeConfigContent = ({ agentNode, attachment, networkS
|
|
|
57
56
|
? {
|
|
58
57
|
dms: {
|
|
59
58
|
enabled: attachment.dms.enabled,
|
|
60
|
-
...(attachment.dms.
|
|
61
|
-
...(attachment.dms.reply ? { reply: attachment.dms.reply } : {})
|
|
59
|
+
...(attachment.dms.wake ? { wake: attachment.dms.wake } : {})
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
: {})
|
|
@@ -52,7 +52,7 @@ const synthesizeRepresentativeAttachments = (memberships) => memberships
|
|
|
52
52
|
teamSource: membership.declaringTeamSource
|
|
53
53
|
}));
|
|
54
54
|
const roomPolicyKey = (policy) => JSON.stringify(policy ?? {});
|
|
55
|
-
const hasRoomPolicy = (policy) => policy.
|
|
55
|
+
const hasRoomPolicy = (policy) => policy.wake !== undefined;
|
|
56
56
|
const mergeAttachment = (target, next, nodeName) => {
|
|
57
57
|
if (target.dms &&
|
|
58
58
|
next.dms &&
|
|
@@ -16,8 +16,7 @@ const findTeamBySource = (plan, source) => {
|
|
|
16
16
|
return node.value;
|
|
17
17
|
};
|
|
18
18
|
const clonePolicy = (policy) => ({
|
|
19
|
-
...(policy.
|
|
20
|
-
...(policy.reply ? { reply: policy.reply } : {})
|
|
19
|
+
...(policy.wake ? { wake: policy.wake } : {})
|
|
21
20
|
});
|
|
22
21
|
const findDirectRoomPolicy = (plan, teamNode, agentSource, memberId, networkId, roomId) => {
|
|
23
22
|
const agentNode = findAgentBySource(plan, agentSource);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { CompilePlan, ResolvedAgentNode } from "./types.js";
|
|
2
|
-
export declare const resolveRuntimeConfig: (plan: CompilePlan, agentNode: ResolvedAgentNode, nodeSlug: string,
|
|
2
|
+
export declare const resolveRuntimeConfig: (plan: CompilePlan, agentNode: ResolvedAgentNode, nodeSlug: string, _networkId: string, _agentId: string) => Record<string, string>;
|