feat: secure organization provider credentials

This commit is contained in:
2026-07-10 22:04:43 +08:00
parent e049cb6880
commit 848f913597
51 changed files with 3280 additions and 230 deletions
+66 -58
View File
@@ -410,63 +410,72 @@ export function makeTriggerHandler(deps: TriggerDeps): TriggerHandler {
// stop the SDK query. Cleared in the finally below.
const abortController = new AbortController();
activeRuns.set(run.id, abortController);
const sdkStderr = createAgentSdkStderrSink({
logger: deps.logger,
runId: run.id,
projectId,
sensitiveValues: Object.values(provider.sdkEnv),
});
runAgent({
prompt: promptForAgent,
model,
project: projectCtx,
systemPrompt,
providerEnv: provider.sdkEnv,
resumeSessionId: sessionMetadata.claudeSessionId,
tools: roleTools,
mcpServers: { cph_hub: fileDeliveryMcpServer },
maxTurns: runPolicy.maxTurns,
runId: run.id,
sessionId: session.id,
prisma: deps.prisma,
abortController,
onSdkStderr: sdkStderr.write,
onStream: (event) => {
switch (event.type) {
case "text-delta":
card.appendText(event.text);
break;
case "thinking-delta":
card.appendReasoning(event.text);
break;
case "tool-start":
card.onToolStart(event.toolName, event.toolUseId);
break;
case "tool-end":
card.onToolEnd({
toolName: event.toolName,
toolUseId: event.toolUseId,
input: event.input,
result: undefined,
error: undefined,
durationMs: event.durationMs,
});
break;
case "tool-result":
card.onToolEnd({
toolName: event.toolName,
toolUseId: event.toolUseId,
input: undefined,
result: event.result,
error: event.isError ? event.result : undefined,
durationMs: event.durationMs,
});
break;
case "finish":
break;
}
},
})
const agentExecution = (async () => {
const providerLease = await provider.openAgentLease({ runId: run.id });
const sdkStderr = createAgentSdkStderrSink({
logger: deps.logger,
runId: run.id,
projectId,
sensitiveValues: providerLease.sensitiveValues,
});
try {
return await runAgent({
prompt: promptForAgent,
model,
project: projectCtx,
systemPrompt,
providerProxyEnv: { ...providerLease.sdkEnv },
resumeSessionId: sessionMetadata.claudeSessionId,
tools: roleTools,
mcpServers: { cph_hub: fileDeliveryMcpServer },
maxTurns: runPolicy.maxTurns,
runId: run.id,
sessionId: session.id,
prisma: deps.prisma,
abortController,
onSdkStderr: sdkStderr.write,
onStream: (event) => {
switch (event.type) {
case "text-delta":
card.appendText(event.text);
break;
case "thinking-delta":
card.appendReasoning(event.text);
break;
case "tool-start":
card.onToolStart(event.toolName, event.toolUseId);
break;
case "tool-end":
card.onToolEnd({
toolName: event.toolName,
toolUseId: event.toolUseId,
input: event.input,
result: undefined,
error: undefined,
durationMs: event.durationMs,
});
break;
case "tool-result":
card.onToolEnd({
toolName: event.toolName,
toolUseId: event.toolUseId,
input: undefined,
result: event.result,
error: event.isError ? event.result : undefined,
durationMs: event.durationMs,
});
break;
case "finish":
break;
}
},
});
} finally {
sdkStderr.flush();
await providerLease.close();
}
})();
agentExecution
.then(async (result) => {
const interrupted = result.status === "interrupted";
const finalText =
@@ -519,7 +528,6 @@ export function makeTriggerHandler(deps: TriggerDeps): TriggerHandler {
await writeAudit(deps.prisma, { runId: run.id, projectId, action: "run.failed", metadata: { error: String(e) } });
})
.finally(async () => {
sdkStderr.flush();
try {
await releaseLock(deps.prisma, run.id);
} catch (e) {