@stigmer/server 3.20.0 → 3.22.0
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/dist/authorization/evaluator.d.ts +7 -1
- package/dist/authorization/evaluator.d.ts.map +1 -1
- package/dist/authorization/evaluator.js.map +1 -1
- package/dist/authorization/list-read-scope.d.ts.map +1 -1
- package/dist/authorization/list-read-scope.js +19 -11
- package/dist/authorization/list-read-scope.js.map +1 -1
- package/dist/authorization/model/organization.d.ts.map +1 -1
- package/dist/authorization/model/organization.js +2 -0
- package/dist/authorization/model/organization.js.map +1 -1
- package/dist/boot/compose.d.ts.map +1 -1
- package/dist/boot/compose.js +0 -1
- package/dist/boot/compose.js.map +1 -1
- package/dist/boot/inprocess.d.ts +0 -2
- package/dist/boot/inprocess.d.ts.map +1 -1
- package/dist/boot/inprocess.js +0 -6
- package/dist/boot/inprocess.js.map +1 -1
- package/dist/domain/agent/controller.d.ts +2 -2
- package/dist/domain/agent/controller.d.ts.map +1 -1
- package/dist/domain/agent/controller.js +3 -17
- package/dist/domain/agent/controller.js.map +1 -1
- package/dist/domain/agent/steps.d.ts +0 -1
- package/dist/domain/agent/steps.d.ts.map +1 -1
- package/dist/domain/agent/steps.js +1 -40
- package/dist/domain/agent/steps.js.map +1 -1
- package/dist/domain/agentchannel/controller.d.ts.map +1 -1
- package/dist/domain/agentchannel/controller.js +6 -1
- package/dist/domain/agentchannel/controller.js.map +1 -1
- package/dist/domain/agentchannel/steps.d.ts +19 -0
- package/dist/domain/agentchannel/steps.d.ts.map +1 -1
- package/dist/domain/agentchannel/steps.js +32 -0
- package/dist/domain/agentchannel/steps.js.map +1 -1
- package/dist/domain/agentexecution/controller.d.ts.map +1 -1
- package/dist/domain/agentexecution/controller.js +7 -9
- package/dist/domain/agentexecution/controller.js.map +1 -1
- package/dist/domain/agentexecution/create-execution-context-step.d.ts +0 -2
- package/dist/domain/agentexecution/create-execution-context-step.d.ts.map +1 -1
- package/dist/domain/agentexecution/create-execution-context-step.js +179 -60
- package/dist/domain/agentexecution/create-execution-context-step.js.map +1 -1
- package/dist/domain/agentexecution/create-steps.d.ts +16 -31
- package/dist/domain/agentexecution/create-steps.d.ts.map +1 -1
- package/dist/domain/agentexecution/create-steps.js +36 -102
- package/dist/domain/agentexecution/create-steps.js.map +1 -1
- package/dist/domain/agentexecution/run-target.d.ts +7 -3
- package/dist/domain/agentexecution/run-target.d.ts.map +1 -1
- package/dist/domain/agentexecution/run-target.js.map +1 -1
- package/dist/domain/agentinstance/controller.d.ts +5 -5
- package/dist/domain/agentinstance/controller.d.ts.map +1 -1
- package/dist/domain/agentinstance/controller.js +6 -1
- package/dist/domain/agentinstance/controller.js.map +1 -1
- package/dist/domain/agentinstance/steps.d.ts +43 -8
- package/dist/domain/agentinstance/steps.d.ts.map +1 -1
- package/dist/domain/agentinstance/steps.js +71 -8
- package/dist/domain/agentinstance/steps.js.map +1 -1
- package/dist/domain/agentshare/controller.d.ts.map +1 -1
- package/dist/domain/agentshare/controller.js +7 -1
- package/dist/domain/agentshare/controller.js.map +1 -1
- package/dist/domain/agentshare/steps.d.ts +58 -0
- package/dist/domain/agentshare/steps.d.ts.map +1 -1
- package/dist/domain/agentshare/steps.js +109 -4
- package/dist/domain/agentshare/steps.js.map +1 -1
- package/dist/domain/artifact/controller.js +21 -25
- package/dist/domain/artifact/controller.js.map +1 -1
- package/dist/domain/channelapp/controller.d.ts.map +1 -1
- package/dist/domain/channelapp/controller.js +2 -0
- package/dist/domain/channelapp/controller.js.map +1 -1
- package/dist/domain/environment/controller.d.ts.map +1 -1
- package/dist/domain/environment/controller.js +2 -0
- package/dist/domain/environment/controller.js.map +1 -1
- package/dist/domain/environment/personal.d.ts +42 -0
- package/dist/domain/environment/personal.d.ts.map +1 -0
- package/dist/domain/environment/personal.js +96 -0
- package/dist/domain/environment/personal.js.map +1 -0
- package/dist/domain/executioncontext/controller.d.ts.map +1 -1
- package/dist/domain/executioncontext/controller.js +2 -0
- package/dist/domain/executioncontext/controller.js.map +1 -1
- package/dist/domain/executioncontext/steps.d.ts.map +1 -1
- package/dist/domain/executioncontext/steps.js +2 -1
- package/dist/domain/executioncontext/steps.js.map +1 -1
- package/dist/domain/mcpserver/connect.d.ts +0 -2
- package/dist/domain/mcpserver/connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/connect.js +24 -79
- package/dist/domain/mcpserver/connect.js.map +1 -1
- package/dist/domain/mcpserver/controller.d.ts.map +1 -1
- package/dist/domain/mcpserver/controller.js +2 -0
- package/dist/domain/mcpserver/controller.js.map +1 -1
- package/dist/domain/mcpserver/start-connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/start-connect.js +8 -7
- package/dist/domain/mcpserver/start-connect.js.map +1 -1
- package/dist/domain/memory/controller.d.ts.map +1 -1
- package/dist/domain/memory/controller.js +6 -1
- package/dist/domain/memory/controller.js.map +1 -1
- package/dist/domain/memory/steps.d.ts +23 -0
- package/dist/domain/memory/steps.d.ts.map +1 -1
- package/dist/domain/memory/steps.js +35 -0
- package/dist/domain/memory/steps.js.map +1 -1
- package/dist/domain/oauthapp/controller.d.ts.map +1 -1
- package/dist/domain/oauthapp/controller.js +2 -0
- package/dist/domain/oauthapp/controller.js.map +1 -1
- package/dist/domain/plugin/controller.d.ts.map +1 -1
- package/dist/domain/plugin/controller.js +5 -24
- package/dist/domain/plugin/controller.js.map +1 -1
- package/dist/domain/plugin/overlay/sanitize.js +2 -2
- package/dist/domain/schedule/controller.d.ts.map +1 -1
- package/dist/domain/schedule/controller.js +7 -1
- package/dist/domain/schedule/controller.js.map +1 -1
- package/dist/domain/schedule/steps.d.ts +19 -0
- package/dist/domain/schedule/steps.d.ts.map +1 -1
- package/dist/domain/schedule/steps.js +32 -0
- package/dist/domain/schedule/steps.js.map +1 -1
- package/dist/domain/session/controller.d.ts +0 -7
- package/dist/domain/session/controller.d.ts.map +1 -1
- package/dist/domain/session/controller.js +11 -16
- package/dist/domain/session/controller.js.map +1 -1
- package/dist/domain/session/run-target.d.ts +9 -8
- package/dist/domain/session/run-target.d.ts.map +1 -1
- package/dist/domain/session/run-target.js.map +1 -1
- package/dist/domain/session/steps.d.ts +8 -36
- package/dist/domain/session/steps.d.ts.map +1 -1
- package/dist/domain/session/steps.js +27 -172
- package/dist/domain/session/steps.js.map +1 -1
- package/dist/domain/skill/controller.d.ts.map +1 -1
- package/dist/domain/skill/controller.js +8 -17
- package/dist/domain/skill/controller.js.map +1 -1
- package/dist/domain/workflow/controller.d.ts.map +1 -1
- package/dist/domain/workflow/controller.js +30 -107
- package/dist/domain/workflow/controller.js.map +1 -1
- package/dist/domain/workflow/version-resolution.d.ts +5 -0
- package/dist/domain/workflow/version-resolution.d.ts.map +1 -0
- package/dist/domain/workflow/version-resolution.js +113 -0
- package/dist/domain/workflow/version-resolution.js.map +1 -0
- package/dist/domain/workflowexecution/create-steps.d.ts +4 -3
- package/dist/domain/workflowexecution/create-steps.d.ts.map +1 -1
- package/dist/domain/workflowexecution/create-steps.js +4 -3
- package/dist/domain/workflowexecution/create-steps.js.map +1 -1
- package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
- package/dist/domain/workflowinstance/controller.js +6 -1
- package/dist/domain/workflowinstance/controller.js.map +1 -1
- package/dist/domain/workflowinstance/steps.d.ts +20 -0
- package/dist/domain/workflowinstance/steps.d.ts.map +1 -1
- package/dist/domain/workflowinstance/steps.js +39 -0
- package/dist/domain/workflowinstance/steps.js.map +1 -1
- package/dist/extensions/identity.d.ts +19 -0
- package/dist/extensions/identity.d.ts.map +1 -1
- package/dist/extensions/identity.js +22 -3
- package/dist/extensions/identity.js.map +1 -1
- package/dist/extensions/list-read-scope.d.ts +41 -7
- package/dist/extensions/list-read-scope.d.ts.map +1 -1
- package/dist/extensions/list-read-scope.js +13 -2
- package/dist/extensions/list-read-scope.js.map +1 -1
- package/dist/pipeline/apiresource-labels.d.ts +2 -2
- package/dist/pipeline/apiresource-labels.js +2 -2
- package/dist/pipeline/errors.d.ts +2 -2
- package/dist/pipeline/errors.js +2 -2
- package/dist/pipeline/steps/authorize-resolved-target.d.ts +88 -0
- package/dist/pipeline/steps/authorize-resolved-target.d.ts.map +1 -0
- package/dist/pipeline/steps/authorize-resolved-target.js +36 -0
- package/dist/pipeline/steps/authorize-resolved-target.js.map +1 -0
- package/dist/pipeline/steps/authorize.d.ts +27 -0
- package/dist/pipeline/steps/authorize.d.ts.map +1 -1
- package/dist/pipeline/steps/authorize.js +49 -10
- package/dist/pipeline/steps/authorize.js.map +1 -1
- package/dist/pipeline/steps/guard-memory-capture.d.ts.map +1 -1
- package/dist/pipeline/steps/guard-memory-capture.js +2 -1
- package/dist/pipeline/steps/guard-memory-capture.js.map +1 -1
- package/dist/pipeline/steps/guard-reserved-labels.d.ts.map +1 -1
- package/dist/pipeline/steps/guard-reserved-labels.js +12 -12
- package/dist/pipeline/steps/guard-reserved-labels.js.map +1 -1
- package/dist/pipeline/steps/helpers.d.ts +9 -5
- package/dist/pipeline/steps/helpers.d.ts.map +1 -1
- package/dist/pipeline/steps/helpers.js +11 -15
- package/dist/pipeline/steps/helpers.js.map +1 -1
- package/dist/pipeline/steps/version-history.d.ts +11 -0
- package/dist/pipeline/steps/version-history.d.ts.map +1 -1
- package/dist/pipeline/steps/version-history.js +26 -0
- package/dist/pipeline/steps/version-history.js.map +1 -1
- package/package.json +6 -6
- package/src/authorization/__tests__/list-read-scope.test.ts +23 -12
- package/src/authorization/__tests__/skip-lane-inventory.test.ts +160 -0
- package/src/authorization/__tests__/wire-permissions.test.ts +5 -5
- package/src/authorization/evaluator.ts +7 -0
- package/src/authorization/list-read-scope.ts +22 -11
- package/src/authorization/model/__tests__/registry.test.ts +2 -0
- package/src/authorization/model/organization.ts +2 -0
- package/src/boot/compose.ts +0 -1
- package/src/boot/inprocess.ts +0 -9
- package/src/domain/agent/__tests__/agent.test.ts +0 -68
- package/src/domain/agent/controller.ts +11 -36
- package/src/domain/agent/steps.ts +1 -60
- package/src/domain/agentchannel/__tests__/create-authorization.test.ts +58 -0
- package/src/domain/agentchannel/controller.ts +19 -0
- package/src/domain/agentchannel/steps.ts +40 -0
- package/src/domain/agentexecution/__tests__/create-execution-context-step.test.ts +216 -0
- package/src/domain/agentexecution/__tests__/create-steps.test.ts +70 -145
- package/src/domain/agentexecution/controller.ts +6 -10
- package/src/domain/agentexecution/create-execution-context-step.ts +271 -83
- package/src/domain/agentexecution/create-steps.ts +38 -138
- package/src/domain/agentexecution/run-target.ts +7 -3
- package/src/domain/agentinstance/__tests__/create-authorization.composed.test.ts +243 -0
- package/src/domain/agentinstance/__tests__/create-authorization.test.ts +144 -0
- package/src/domain/agentinstance/controller.ts +24 -5
- package/src/domain/agentinstance/steps.ts +82 -8
- package/src/domain/agentshare/__tests__/create-authorization.test.ts +86 -0
- package/src/domain/agentshare/__tests__/member-audience.test.ts +113 -0
- package/src/domain/agentshare/controller.ts +21 -0
- package/src/domain/agentshare/steps.ts +181 -15
- package/src/domain/artifact/controller.ts +18 -22
- package/src/domain/channelapp/controller.ts +10 -0
- package/src/domain/environment/__tests__/personal.test.ts +143 -0
- package/src/domain/environment/controller.ts +10 -0
- package/src/domain/environment/personal.ts +141 -0
- package/src/domain/executioncontext/__tests__/executioncontext.test.ts +1 -0
- package/src/domain/executioncontext/controller.ts +10 -0
- package/src/domain/executioncontext/steps.ts +2 -1
- package/src/domain/mcpserver/connect.ts +32 -92
- package/src/domain/mcpserver/controller.ts +13 -1
- package/src/domain/mcpserver/start-connect.ts +17 -11
- package/src/domain/memory/__tests__/create-authorization.test.ts +59 -0
- package/src/domain/memory/controller.ts +11 -0
- package/src/domain/memory/steps.ts +41 -0
- package/src/domain/oauthapp/controller.ts +10 -0
- package/src/domain/plugin/controller.ts +22 -36
- package/src/domain/plugin/overlay/sanitize.ts +2 -2
- package/src/domain/schedule/__tests__/create-authorization.test.ts +58 -0
- package/src/domain/schedule/controller.ts +20 -0
- package/src/domain/schedule/steps.ts +45 -2
- package/src/domain/session/__tests__/run-gate.test.ts +19 -52
- package/src/domain/session/__tests__/session.test.ts +27 -203
- package/src/domain/session/controller.ts +10 -30
- package/src/domain/session/run-target.ts +9 -8
- package/src/domain/session/steps.ts +33 -267
- package/src/domain/skill/controller.ts +24 -23
- package/src/domain/workflow/controller.ts +58 -145
- package/src/domain/workflow/version-resolution.ts +166 -0
- package/src/domain/workflowexecution/create-steps.ts +4 -3
- package/src/domain/workflowinstance/__tests__/create-authorization.test.ts +109 -0
- package/src/domain/workflowinstance/controller.ts +19 -0
- package/src/domain/workflowinstance/steps.ts +49 -1
- package/src/extensions/__tests__/composed-support.ts +38 -4
- package/src/extensions/__tests__/identity.test.ts +44 -1
- package/src/extensions/__tests__/list-read-scope-composed.test.ts +87 -1
- package/src/extensions/__tests__/list-read-scope.test.ts +63 -0
- package/src/extensions/identity.ts +23 -5
- package/src/extensions/list-read-scope.ts +47 -7
- package/src/pipeline/apiresource-labels.ts +2 -2
- package/src/pipeline/errors.ts +2 -2
- package/src/pipeline/steps/__tests__/authorize-resolved-target.test.ts +285 -0
- package/src/pipeline/steps/authorize-resolved-target.ts +129 -0
- package/src/pipeline/steps/authorize.ts +70 -13
- package/src/pipeline/steps/guard-memory-capture.ts +2 -1
- package/src/pipeline/steps/guard-reserved-labels.ts +12 -14
- package/src/pipeline/steps/helpers.ts +11 -15
- package/src/pipeline/steps/version-history.ts +34 -0
- package/dist/domain/agent/defaultagent.d.ts +0 -37
- package/dist/domain/agent/defaultagent.d.ts.map +0 -1
- package/dist/domain/agent/defaultagent.js +0 -104
- package/dist/domain/agent/defaultagent.js.map +0 -1
- package/src/domain/agent/defaultagent.ts +0 -135
|
@@ -11,15 +11,26 @@
|
|
|
11
11
|
* Resolution chain:
|
|
12
12
|
* - Path A (preResolvedInstanceId): agentInstanceLoader → agentLoader
|
|
13
13
|
* - Path B (session_id): sessionLoader → session.agent_instance_id →
|
|
14
|
-
* agentInstanceLoader → agentLoader
|
|
14
|
+
* agentInstanceLoader → agentLoader; an EMPTY agent_instance_id is the
|
|
15
|
+
* built-in assistant (session/v1/spec.proto): no instance, no agent,
|
|
16
|
+
* no instance layers, and the session's own MCP servers are the whole
|
|
17
|
+
* tool set.
|
|
15
18
|
*
|
|
16
19
|
* Merge priority (lowest to highest): schedule/workflow-task
|
|
17
20
|
* environment_refs (the share/channel/schedule/agent_call layering) →
|
|
18
21
|
* instance environment_refs (via the environment RuntimeResolutionService
|
|
19
22
|
* — decrypted, the RPC surface redacts, oss#405) → spec.runtime_env.
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
+
*
|
|
24
|
+
* Then ONE declaration rule for every shape: the run declares what its
|
|
25
|
+
* agent declares and what its session's MCP servers declare, and the
|
|
26
|
+
* least-privilege filter keeps exactly those keys. A session server rides
|
|
27
|
+
* no agent instance, so its declared variables have no environment_refs
|
|
28
|
+
* to arrive through; the ones still missing after the merge are resolved
|
|
29
|
+
* the way the MCP connect lane resolves them — OAuth tokens from the
|
|
30
|
+
* managed grant, the rest from the caller's personal environment, by
|
|
31
|
+
* declared key only (domain/environment/personal.ts). The built-in
|
|
32
|
+
* assistant is the case with no agent half, not an arm of its own.
|
|
33
|
+
* Around that rule: the workspace-provisioning re-injection, and the
|
|
23
34
|
* required-keys warning.
|
|
24
35
|
*/
|
|
25
36
|
import { create } from "@bufbuild/protobuf";
|
|
@@ -37,12 +48,16 @@ import {
|
|
|
37
48
|
ListEnvironmentsRequestSchema,
|
|
38
49
|
} from "@stigmer/protos/ai/stigmer/agentic/environment/v1/io_pb";
|
|
39
50
|
import { EnvironmentValueSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/spec_pb";
|
|
40
|
-
import type {
|
|
51
|
+
import type {
|
|
52
|
+
EnvVarDeclaration,
|
|
53
|
+
EnvironmentValue,
|
|
54
|
+
} from "@stigmer/protos/ai/stigmer/agentic/environment/v1/spec_pb";
|
|
41
55
|
import type { ExecutionContext } from "@stigmer/protos/ai/stigmer/agentic/executioncontext/v1/api_pb";
|
|
42
56
|
import { ExecutionContextSchema } from "@stigmer/protos/ai/stigmer/agentic/executioncontext/v1/api_pb";
|
|
43
57
|
import type { ExecutionValue } from "@stigmer/protos/ai/stigmer/agentic/executioncontext/v1/spec_pb";
|
|
44
58
|
import { ExecutionValueSchema } from "@stigmer/protos/ai/stigmer/agentic/executioncontext/v1/spec_pb";
|
|
45
59
|
import { McpServerSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
|
|
60
|
+
import type { McpServer } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
|
|
46
61
|
import { ScheduleSchema } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
|
|
47
62
|
import type { Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
|
|
48
63
|
import { WorkflowSchema } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/api_pb";
|
|
@@ -72,6 +87,12 @@ import type { PipelineStep } from "../../pipeline/pipeline.js";
|
|
|
72
87
|
import { findResourceBySlug } from "../../pipeline/steps/helpers.js";
|
|
73
88
|
import { ResourceNotFoundError } from "../../store/interface.js";
|
|
74
89
|
import type { OAuthGrant, Store } from "../../store/interface.js";
|
|
90
|
+
import {
|
|
91
|
+
PERSONAL_LABEL_KEY,
|
|
92
|
+
PERSONAL_LABEL_VALUE,
|
|
93
|
+
} from "../environment/constants.js";
|
|
94
|
+
import { resolveDeclaredFromPersonalEnvironment } from "../environment/personal.js";
|
|
95
|
+
import type { PersonalEnvironmentResolution } from "../environment/personal.js";
|
|
75
96
|
import type { RuntimeResolutionService } from "../environment/resolution/resolution.js";
|
|
76
97
|
import type { ManagedEnvironmentService } from "../mcpserver/oauth/managed-env.js";
|
|
77
98
|
import { refreshTokenIfExpired } from "../mcpserver/oauth/refresh.js";
|
|
@@ -107,9 +128,6 @@ export const WORKFLOW_TASK_LABEL_KEY = "stigmer.ai/workflow-task";
|
|
|
107
128
|
*/
|
|
108
129
|
export const WORKSPACE_PROVISIONING_KEYS = ["GITHUB_TOKEN"];
|
|
109
130
|
|
|
110
|
-
/** The well-known label identifying a user's personal environment. */
|
|
111
|
-
export const PERSONAL_ENV_LABEL = "stigmer.ai/personal";
|
|
112
|
-
|
|
113
131
|
// ---------------------------------------------------------------------------
|
|
114
132
|
// The narrow in-process edges the builder consumes (DD-002 lazy providers).
|
|
115
133
|
// ---------------------------------------------------------------------------
|
|
@@ -206,48 +224,77 @@ export async function buildAndPersistExecutionContext(
|
|
|
206
224
|
const executionId = execution.metadata?.id ?? "";
|
|
207
225
|
const executionOrg = execution.metadata?.org ?? "";
|
|
208
226
|
|
|
209
|
-
// 1. Resolve
|
|
210
|
-
|
|
227
|
+
// 1. Resolve the target: the instance the run is bound to, and the
|
|
228
|
+
// session when Path B loaded it on the way. An empty instance id with a
|
|
229
|
+
// session is the built-in assistant.
|
|
230
|
+
let target: ResolvedTarget;
|
|
211
231
|
try {
|
|
212
|
-
|
|
213
|
-
deps,
|
|
214
|
-
execution,
|
|
215
|
-
preResolvedInstanceId,
|
|
216
|
-
);
|
|
232
|
+
target = await resolveTarget(deps, execution, preResolvedInstanceId);
|
|
217
233
|
} catch (error) {
|
|
218
234
|
chainError("resolve agent instance", error);
|
|
219
235
|
}
|
|
236
|
+
const { agentInstanceId } = target;
|
|
237
|
+
let session = target.session;
|
|
220
238
|
|
|
221
239
|
// 2.–3. Load the instance (environment_refs + agent_id), then the
|
|
222
240
|
// agent (env declarations) — in-process, full chain traversal. Load
|
|
223
|
-
// failures keep the inner status code with Go's wrap prefix.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
)
|
|
241
|
+
// failures keep the inner status code with Go's wrap prefix. Neither
|
|
242
|
+
// exists for the built-in assistant.
|
|
243
|
+
let instance: AgentInstance | undefined;
|
|
244
|
+
let agentResource: Agent | undefined;
|
|
245
|
+
let agentId = "";
|
|
246
|
+
if (agentInstanceId !== "") {
|
|
247
|
+
try {
|
|
248
|
+
instance = await deps.agentInstanceLoader().get(agentInstanceId);
|
|
249
|
+
} catch (error) {
|
|
250
|
+
if (error instanceof ConnectError) {
|
|
251
|
+
throw goWrappedStatusError(
|
|
252
|
+
`load agent instance ${agentInstanceId}`,
|
|
253
|
+
error,
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
chainError(`load agent instance ${agentInstanceId}`, error);
|
|
257
|
+
}
|
|
258
|
+
agentId = instance.spec?.agentId ?? "";
|
|
259
|
+
try {
|
|
260
|
+
agentResource = await deps.agentLoader().get(agentId);
|
|
261
|
+
} catch (error) {
|
|
262
|
+
if (error instanceof ConnectError) {
|
|
263
|
+
throw goWrappedStatusError(`load agent ${agentId}`, error);
|
|
264
|
+
}
|
|
265
|
+
chainError(`load agent ${agentId}`, error);
|
|
233
266
|
}
|
|
234
|
-
chainError(`load agent instance ${agentInstanceId}`, error);
|
|
235
267
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
268
|
+
|
|
269
|
+
// 3.5 The session, when Path A did not load it: its workspace entries
|
|
270
|
+
// and its own MCP servers shape the environment below. A failed load is
|
|
271
|
+
// non-fatal for an agent-bound run (the agent's declarations still
|
|
272
|
+
// stand); the built-in assistant always arrives through Path B, so its
|
|
273
|
+
// session is already in hand or the resolve above refused.
|
|
274
|
+
const sessionId = execution.spec?.sessionId ?? "";
|
|
275
|
+
if (session === undefined && sessionId !== "") {
|
|
276
|
+
try {
|
|
277
|
+
session = await deps.sessionLoader().get(sessionId);
|
|
278
|
+
} catch (error) {
|
|
279
|
+
deps.logger.warn(
|
|
280
|
+
"Failed to load session for environment resolution (non-fatal)",
|
|
281
|
+
{
|
|
282
|
+
executionId,
|
|
283
|
+
error: error instanceof Error ? error.message : String(error),
|
|
284
|
+
},
|
|
285
|
+
);
|
|
243
286
|
}
|
|
244
|
-
chainError(`load agent ${agentId}`, error);
|
|
245
287
|
}
|
|
288
|
+
const sessionMcpServers = await loadSessionMcpServers(
|
|
289
|
+
deps,
|
|
290
|
+
session,
|
|
291
|
+
executionOrg,
|
|
292
|
+
);
|
|
246
293
|
|
|
247
294
|
// 4. Resolve environments from instance environment_refs.
|
|
248
295
|
let environments = await resolveEnvironments(
|
|
249
296
|
deps,
|
|
250
|
-
instance
|
|
297
|
+
instance?.spec?.environmentRefs ?? [],
|
|
251
298
|
);
|
|
252
299
|
|
|
253
300
|
// 4.5 Schedule-created executions: the schedule's own environment_refs
|
|
@@ -282,13 +329,17 @@ export async function buildAndPersistExecutionContext(
|
|
|
282
329
|
execution.spec?.runtimeEnv ?? {},
|
|
283
330
|
);
|
|
284
331
|
|
|
285
|
-
// 6. Least-privilege whitelist
|
|
286
|
-
//
|
|
287
|
-
|
|
288
|
-
const
|
|
332
|
+
// 6. Least-privilege whitelist over the ONE declared set: the agent's
|
|
333
|
+
// env united with the session servers' env (the module header's rule).
|
|
334
|
+
// Empty declarations pass everything through.
|
|
335
|
+
const declarations = unionDeclarations(
|
|
336
|
+
agentResource?.spec?.env ?? {},
|
|
337
|
+
sessionMcpServers,
|
|
338
|
+
);
|
|
339
|
+
const filterResult = filterByDeclaredKeys(merged, declarations);
|
|
289
340
|
let filtered = filterResult.filtered;
|
|
290
341
|
if (filterResult.excludedKeys.length > 0) {
|
|
291
|
-
deps.logger.warn("Filtered env vars not declared
|
|
342
|
+
deps.logger.warn("Filtered env vars not declared by the agent or the session's servers", {
|
|
292
343
|
executionId,
|
|
293
344
|
agentId,
|
|
294
345
|
excludedKeys: filterResult.excludedKeys,
|
|
@@ -297,40 +348,25 @@ export async function buildAndPersistExecutionContext(
|
|
|
297
348
|
|
|
298
349
|
// 6.5 Re-inject workspace-provisioning keys excluded by the filter,
|
|
299
350
|
// and fall back to the caller's personal environment for keys never in
|
|
300
|
-
// the merge chain at all.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
filtered = injectWorkspaceProvisioningKeys(
|
|
317
|
-
deps.logger,
|
|
318
|
-
filtered,
|
|
319
|
-
merged,
|
|
320
|
-
session,
|
|
321
|
-
executionId,
|
|
322
|
-
);
|
|
323
|
-
filtered = await injectFromPersonalEnvironment(
|
|
324
|
-
deps,
|
|
325
|
-
filtered,
|
|
326
|
-
session,
|
|
327
|
-
executionOrg,
|
|
328
|
-
executionId,
|
|
329
|
-
);
|
|
330
|
-
}
|
|
351
|
+
// the merge chain at all.
|
|
352
|
+
if (session !== undefined) {
|
|
353
|
+
filtered = injectWorkspaceProvisioningKeys(
|
|
354
|
+
deps.logger,
|
|
355
|
+
filtered,
|
|
356
|
+
merged,
|
|
357
|
+
session,
|
|
358
|
+
executionId,
|
|
359
|
+
);
|
|
360
|
+
filtered = await injectFromPersonalEnvironment(
|
|
361
|
+
deps,
|
|
362
|
+
filtered,
|
|
363
|
+
session,
|
|
364
|
+
executionOrg,
|
|
365
|
+
executionId,
|
|
366
|
+
);
|
|
331
367
|
}
|
|
332
368
|
|
|
333
|
-
// 6.
|
|
369
|
+
// 6.8 Inject OAuth tokens from managed environments — iterated
|
|
334
370
|
// over the merged agent + session MCP usages so session-level servers
|
|
335
371
|
// (added at runtime) get their tokens too. Refresh failures are FATAL
|
|
336
372
|
// (FailedPrecondition): an expired token must prevent execution rather
|
|
@@ -353,9 +389,21 @@ export async function buildAndPersistExecutionContext(
|
|
|
353
389
|
);
|
|
354
390
|
}
|
|
355
391
|
|
|
392
|
+
// 6.85 The session servers' declared variables the chain did not carry
|
|
393
|
+
// (no instance layer ever could): the caller's personal environment, by
|
|
394
|
+
// declared key. Non-fatal — the run fails at the tool with a clearer
|
|
395
|
+
// error if a key is truly required, the posture of every fallback here.
|
|
396
|
+
filtered = await injectSessionServerDeclaredFromPersonalEnvironment(
|
|
397
|
+
deps,
|
|
398
|
+
filtered,
|
|
399
|
+
sessionMcpServers,
|
|
400
|
+
executionOrg,
|
|
401
|
+
executionId,
|
|
402
|
+
);
|
|
403
|
+
|
|
356
404
|
// 6.9 Warn on missing required declared vars — the downstream
|
|
357
405
|
// execution fails with a clearer error if truly needed.
|
|
358
|
-
const missingRequired = validateRequiredKeys(filtered,
|
|
406
|
+
const missingRequired = validateRequiredKeys(filtered, declarations);
|
|
359
407
|
if (missingRequired.length > 0) {
|
|
360
408
|
deps.logger.warn(
|
|
361
409
|
"Required env vars missing after environment merge — execution may fail",
|
|
@@ -367,7 +415,8 @@ export async function buildAndPersistExecutionContext(
|
|
|
367
415
|
executionId,
|
|
368
416
|
mergedCount: merged.size,
|
|
369
417
|
filteredCount: filtered.size,
|
|
370
|
-
environmentRefsCount: instance
|
|
418
|
+
environmentRefsCount: instance?.spec?.environmentRefs.length ?? 0,
|
|
419
|
+
builtInAssistant: agentInstanceId === "",
|
|
371
420
|
});
|
|
372
421
|
|
|
373
422
|
// 7. Build and persist the ExecutionContext through the in-process
|
|
@@ -423,14 +472,26 @@ function chainError(prefix: string, error: unknown): never {
|
|
|
423
472
|
);
|
|
424
473
|
}
|
|
425
474
|
|
|
426
|
-
/**
|
|
427
|
-
|
|
475
|
+
/**
|
|
476
|
+
* The run's target (Go resolveAgentInstanceID, widened): Path A answers
|
|
477
|
+
* the pre-resolved instance alone; Path B loads the session and answers
|
|
478
|
+
* its instance, which is "" for the built-in assistant, together with the
|
|
479
|
+
* session so the caller does not load it twice. A persisted execution
|
|
480
|
+
* always carries session_id (lifecycle.ts recover), so the no-session arm
|
|
481
|
+
* is an invariant, not a shape.
|
|
482
|
+
*/
|
|
483
|
+
interface ResolvedTarget {
|
|
484
|
+
readonly agentInstanceId: string;
|
|
485
|
+
readonly session: Session | undefined;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
async function resolveTarget(
|
|
428
489
|
deps: ExecutionContextBuilderDeps,
|
|
429
490
|
execution: AgentExecution,
|
|
430
491
|
preResolvedInstanceId: string,
|
|
431
|
-
): Promise<
|
|
492
|
+
): Promise<ResolvedTarget> {
|
|
432
493
|
if (preResolvedInstanceId !== "") {
|
|
433
|
-
return preResolvedInstanceId;
|
|
494
|
+
return { agentInstanceId: preResolvedInstanceId, session: undefined };
|
|
434
495
|
}
|
|
435
496
|
const sessionId = execution.spec?.sessionId ?? "";
|
|
436
497
|
if (sessionId === "") {
|
|
@@ -449,11 +510,138 @@ async function resolveAgentInstanceId(
|
|
|
449
510
|
`load session ${sessionId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
450
511
|
);
|
|
451
512
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
513
|
+
return { agentInstanceId: session.spec?.agentInstanceId ?? "", session };
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Loads the MCP servers a session declares on its own (spec.mcp_server_usages),
|
|
518
|
+
* by slug in the usage's org or the execution's. A server that cannot be
|
|
519
|
+
* found is skipped: the runner resolves the same usages for real and
|
|
520
|
+
* refuses there with the tool's own error; this pass only needs the
|
|
521
|
+
* declarations of the servers that exist.
|
|
522
|
+
*/
|
|
523
|
+
async function loadSessionMcpServers(
|
|
524
|
+
deps: ExecutionContextBuilderDeps,
|
|
525
|
+
session: Session | undefined,
|
|
526
|
+
executionOrg: string,
|
|
527
|
+
): Promise<McpServer[]> {
|
|
528
|
+
const servers: McpServer[] = [];
|
|
529
|
+
for (const usage of session?.spec?.mcpServerUsages ?? []) {
|
|
530
|
+
const slug = usage.mcpServerRef?.slug ?? "";
|
|
531
|
+
const org = usage.mcpServerRef?.org || executionOrg;
|
|
532
|
+
if (slug === "" || org === "") {
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
let server: McpServer | undefined;
|
|
536
|
+
try {
|
|
537
|
+
server = await findResourceBySlug(
|
|
538
|
+
deps.store,
|
|
539
|
+
ApiResourceKind.mcp_server,
|
|
540
|
+
McpServerSchema,
|
|
541
|
+
slug,
|
|
542
|
+
org,
|
|
543
|
+
);
|
|
544
|
+
} catch {
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
if (server !== undefined) {
|
|
548
|
+
servers.push(server);
|
|
549
|
+
}
|
|
455
550
|
}
|
|
456
|
-
return
|
|
551
|
+
return servers;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* The one declared set of a run: the agent's env declarations united with
|
|
556
|
+
* every session server's. On a key both declare, the agent's declaration
|
|
557
|
+
* wins (it is the author's word for the run as a whole; the server's is
|
|
558
|
+
* the tool's word for itself).
|
|
559
|
+
*/
|
|
560
|
+
function unionDeclarations(
|
|
561
|
+
agentEnv: { readonly [key: string]: EnvVarDeclaration },
|
|
562
|
+
sessionMcpServers: readonly McpServer[],
|
|
563
|
+
): { [key: string]: EnvVarDeclaration } {
|
|
564
|
+
const union: { [key: string]: EnvVarDeclaration } = {};
|
|
565
|
+
for (const server of sessionMcpServers) {
|
|
566
|
+
Object.assign(union, server.spec?.env ?? {});
|
|
567
|
+
}
|
|
568
|
+
Object.assign(union, agentEnv);
|
|
569
|
+
return union;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Resolves the session servers' declared variables still missing after
|
|
574
|
+
* the merge and the OAuth injection from the caller's personal
|
|
575
|
+
* environment, by declared key. OAuth-target variables are left to the
|
|
576
|
+
* managed grant (an absent grant is the sign-in the console asks for, not
|
|
577
|
+
* a personal-environment lookup). Every failure is non-fatal here: a
|
|
578
|
+
* missing key is logged and the run meets the tool's own error.
|
|
579
|
+
*/
|
|
580
|
+
async function injectSessionServerDeclaredFromPersonalEnvironment(
|
|
581
|
+
deps: ExecutionContextBuilderDeps,
|
|
582
|
+
filtered: Map<string, ExecutionValue>,
|
|
583
|
+
sessionMcpServers: readonly McpServer[],
|
|
584
|
+
executionOrg: string,
|
|
585
|
+
executionId: string,
|
|
586
|
+
): Promise<Map<string, ExecutionValue>> {
|
|
587
|
+
const wanted: { [key: string]: EnvVarDeclaration } = {};
|
|
588
|
+
for (const server of sessionMcpServers) {
|
|
589
|
+
const oauthKey = server.spec?.auth?.targetEnvVar ?? "";
|
|
590
|
+
for (const [key, decl] of Object.entries(server.spec?.env ?? {})) {
|
|
591
|
+
if (key === oauthKey || filtered.has(key)) {
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
wanted[key] = decl;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
if (Object.keys(wanted).length === 0 || executionOrg === "") {
|
|
598
|
+
return filtered;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
let resolution: PersonalEnvironmentResolution;
|
|
602
|
+
try {
|
|
603
|
+
resolution = await resolveDeclaredFromPersonalEnvironment(
|
|
604
|
+
deps.environmentReader(),
|
|
605
|
+
deps.logger,
|
|
606
|
+
executionOrg,
|
|
607
|
+
wanted,
|
|
608
|
+
);
|
|
609
|
+
} catch (error) {
|
|
610
|
+
deps.logger.warn(
|
|
611
|
+
"Failed to resolve session servers' variables from the personal environment (non-fatal)",
|
|
612
|
+
{
|
|
613
|
+
executionId,
|
|
614
|
+
error: error instanceof Error ? error.message : String(error),
|
|
615
|
+
},
|
|
616
|
+
);
|
|
617
|
+
return filtered;
|
|
618
|
+
}
|
|
619
|
+
if (resolution.kind === "no-personal-environment") {
|
|
620
|
+
deps.logger.debug(
|
|
621
|
+
"No personal environment — session servers' declared variables stay unresolved",
|
|
622
|
+
{ executionId, keys: Object.keys(wanted).sort() },
|
|
623
|
+
);
|
|
624
|
+
return filtered;
|
|
625
|
+
}
|
|
626
|
+
if (resolution.missing.length > 0) {
|
|
627
|
+
deps.logger.warn(
|
|
628
|
+
"Session servers declare required variables the personal environment does not hold",
|
|
629
|
+
{ executionId, missing: [...resolution.missing].sort() },
|
|
630
|
+
);
|
|
631
|
+
}
|
|
632
|
+
const entries = Object.entries(resolution.values);
|
|
633
|
+
if (entries.length === 0) {
|
|
634
|
+
return filtered;
|
|
635
|
+
}
|
|
636
|
+
const out = new Map(filtered);
|
|
637
|
+
for (const [key, value] of entries) {
|
|
638
|
+
out.set(key, value);
|
|
639
|
+
}
|
|
640
|
+
deps.logger.info(
|
|
641
|
+
"Injected session servers' declared variables from the caller's personal environment",
|
|
642
|
+
{ executionId, keys: entries.map(([key]) => key).sort() },
|
|
643
|
+
);
|
|
644
|
+
return out;
|
|
457
645
|
}
|
|
458
646
|
|
|
459
647
|
/**
|
|
@@ -785,7 +973,7 @@ async function injectFromPersonalEnvironment(
|
|
|
785
973
|
listResponse = await deps.environmentReader().list(
|
|
786
974
|
create(ListEnvironmentsRequestSchema, {
|
|
787
975
|
org: executionOrg,
|
|
788
|
-
labels: { [
|
|
976
|
+
labels: { [PERSONAL_LABEL_KEY]: PERSONAL_LABEL_VALUE },
|
|
789
977
|
}),
|
|
790
978
|
);
|
|
791
979
|
} catch (error) {
|