diff --git a/config/hwlab-node-lanes.yaml b/config/hwlab-node-lanes.yaml index 6dfea5fa..471561d3 100644 --- a/config/hwlab-node-lanes.yaml +++ b/config/hwlab-node-lanes.yaml @@ -290,6 +290,11 @@ lanes: apiKeySecretKey: api-key runnerNamespace: agentrun-v02 secretNamespace: agentrun-v02 + providerSecretNames: + codex: agentrun-v01-provider-codex + gpt-pika: agentrun-v02-provider-gpt-pika + grok: agentrun-v02-provider-grok + dsflash-go: agentrun-v01-provider-dsflash-go toolSecretNames: githubPr: agentrun-v01-tool-github-pr unideskSsh: agentrun-v01-tool-unidesk-ssh diff --git a/docs/MDTODO/hwlab-web-product-experience.md b/docs/MDTODO/hwlab-web-product-experience.md index c0869c9d..af991cc5 100644 --- a/docs/MDTODO/hwlab-web-product-experience.md +++ b/docs/MDTODO/hwlab-web-product-experience.md @@ -115,3 +115,7 @@ ### R6.1 [in_progress] 执行 [UniDesk #2529](https://github.com/pikasTech/unidesk/issues/2529):将 Workbench L1 用户入口通过 owning YAML 与 shared public-edge 固定暴露为 `https://lab-dev-workbench.hwpod.com`,CLI 与 `web-probe native-readiness` 只消费固定 HTTPS origin;内部 IP/port 仅用于 bind/probe,端口冲突时修改 YAML 且域名不变;在开发等级 SKILL 中规定所有 L1 一律使用 YAML 固定 HTTPS 域名,并要求执行 L1 时发现历史未暴露实例就逐例登记、治理和验收后再继续,完成任务后将详细报告写入[任务报告](./details/hwlab-web-product-experience/R6.1_Task_Report.md)。 + +#### R6.1.1 [in_progress] + +修复 [UniDesk #2531](https://github.com/pikasTech/unidesk/issues/2531):复用 AgentRun nc01-v02 owning YAML 的现有 provider/tool SecretRef,补齐 Workbench L1 native environment 的 namespace、provider Secret name 和 tool Secret name 映射,禁止创建、复制或反解密钥,并以固定 HTTPS typed CLI 和纯 Kafka SSE 完成 `gpt.pika` smoke,完成任务后将详细报告写入[任务报告](./details/hwlab-web-product-experience/R6.1.1_Task_Report.md)。 diff --git a/scripts/src/hwlab-native-development.test.ts b/scripts/src/hwlab-native-development.test.ts index a0aa3495..bc1728c6 100644 --- a/scripts/src/hwlab-native-development.test.ts +++ b/scripts/src/hwlab-native-development.test.ts @@ -17,6 +17,11 @@ test("L1 Workbench exposure uses YAML HTTPS origin and separate bind/probe addre expect(env.AGENTRUN_MGR_URL).toBe(native!.agentRun.managerUrl); expect(env.AGENTRUN_API_KEY).toMatch(/^hwl_live_/u); expect(env.HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE).toBe("gpt.pika"); + expect(env.HWLAB_CODE_AGENT_AGENTRUN_SECRET_NAMESPACE).toBe("agentrun-v02"); + expect(env.HWLAB_CODE_AGENT_AGENTRUN_GPT_PIKA_SECRET_NAME).toBe("agentrun-v02-provider-gpt-pika"); + expect(env.HWLAB_CODE_AGENT_AGENTRUN_CODEX_SECRET_NAME).toBe("agentrun-v01-provider-codex"); + expect(env.HWLAB_CODE_AGENT_AGENTRUN_GITHUB_TOOL_SECRET_NAME).toBe("agentrun-v01-tool-github-pr"); + expect(env.HWLAB_CODE_AGENT_AGENTRUN_UNIDESK_SSH_TOOL_SECRET_NAME).toBe("agentrun-v01-tool-unidesk-ssh"); expect(env.HWLAB_CODE_AGENT_AGENTRUN_SOURCE_COMMIT).toBe("0123456789abcdef0123456789abcdef01234567"); expect(env.HWLAB_KAFKA_DIRECT_PUBLISH_ENABLED).toBe("false"); expect(env.HWLAB_WORKBENCH_LIVE_KAFKA_SSE_ENABLED).toBe("true"); diff --git a/scripts/src/hwlab-native-development.ts b/scripts/src/hwlab-native-development.ts index 1f25a1f1..1ee22b42 100644 --- a/scripts/src/hwlab-native-development.ts +++ b/scripts/src/hwlab-native-development.ts @@ -68,6 +68,10 @@ export function hwlabNativeDevelopmentEnvironment(native: HwlabRuntimeNativeDeve if (kafkaBridge === undefined) throw new Error(`${hwlabRuntimeLaneConfigPath()}#lanes.${spec.lane}.targets.${spec.nodeId}.${native.kafka.configRef} is required`); if (native.kafka.hwlabEventConsumerGroupId === kafkaBridge.hwlabEventConsumerGroupId) throw new Error("native Workbench Kafka consumer group must be distinct from the Cloud API live SSE consumer group"); if (!/^[0-9a-f]{40}$/iu.test(sourceCommit)) throw new Error("sourceCommit must be the current HWLAB workspace 40-hex git SHA"); + const providerSecretNames = codeAgent.providerSecretNames; + if (providerSecretNames === undefined) throw new Error(`${hwlabRuntimeLaneConfigPath()}#lanes.${spec.lane}.targets.${spec.nodeId}.codeAgentRuntime.providerSecretNames is required`); + const defaultProviderKey = codeAgent.defaultProviderProfile.toLowerCase().replace(/[^a-z0-9]+/gu, "-"); + if (!providerSecretNames[defaultProviderKey]) throw new Error(`codeAgentRuntime.providerSecretNames.${defaultProviderKey} is required for defaultProviderProfile=${codeAgent.defaultProviderProfile}`); const authorizationSource = readEnvSourceFile({ root: "/root/.unidesk/.state/secrets", sourceRef: codeAgent.apiKeySourceRef, @@ -89,6 +93,10 @@ export function hwlabNativeDevelopmentEnvironment(native: HwlabRuntimeNativeDeve HWLAB_CODE_AGENT_AGENTRUN_PROVIDER_ID: spec.nodeId, HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE: codeAgent.defaultProviderProfile, HWLAB_CODE_AGENT_AGENTRUN_RUNNER_NAMESPACE: codeAgent.runnerNamespace, + HWLAB_CODE_AGENT_AGENTRUN_SECRET_NAMESPACE: codeAgent.secretNamespace, + ...providerSecretNameEnvironment(providerSecretNames), + HWLAB_CODE_AGENT_AGENTRUN_GITHUB_TOOL_SECRET_NAME: codeAgent.toolSecretNames.githubPr, + HWLAB_CODE_AGENT_AGENTRUN_UNIDESK_SSH_TOOL_SECRET_NAME: codeAgent.toolSecretNames.unideskSsh, HWLAB_CODE_AGENT_AGENTRUN_REPO_URL: spec.gitReadUrl, HWLAB_CODE_AGENT_AGENTRUN_SOURCE_COMMIT: sourceCommit, HWLAB_RUNTIME_API_URL: native.agentRun.runtimeApiUrl, @@ -127,6 +135,13 @@ export function hwlabNativeDevelopmentEnvironment(native: HwlabRuntimeNativeDeve }; } +function providerSecretNameEnvironment(providerSecretNames: Readonly>): NodeJS.ProcessEnv { + return Object.fromEntries(Object.entries(providerSecretNames).map(([profile, secretName]) => { + const profileKey = profile.toUpperCase().replace(/[^A-Z0-9]+/gu, "_"); + return [`HWLAB_CODE_AGENT_AGENTRUN_${profileKey}_SECRET_NAME`, secretName]; + })); +} + function parsePayload(stdout: string): Record { const parsed = JSON.parse(stdout) as unknown; if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new Error("HWLAB Workbench CLI returned invalid JSON");