@stigmer/server 3.20.0 → 3.21.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/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 +1 -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/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/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/mcpserver/connect.d.ts +0 -2
- package/dist/domain/mcpserver/connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/connect.js +16 -72
- package/dist/domain/mcpserver/connect.js.map +1 -1
- package/dist/domain/plugin/overlay/sanitize.js +2 -2
- 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 +0 -27
- package/dist/domain/session/steps.d.ts.map +1 -1
- package/dist/domain/session/steps.js +10 -151
- package/dist/domain/session/steps.js.map +1 -1
- 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/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/guard-reserved-labels.d.ts.map +1 -1
- package/dist/pipeline/steps/guard-reserved-labels.js +6 -5
- package/dist/pipeline/steps/guard-reserved-labels.js.map +1 -1
- package/package.json +6 -6
- 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 +3 -38
- package/src/domain/agent/steps.ts +1 -60
- 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/environment/__tests__/personal.test.ts +143 -0
- package/src/domain/environment/personal.ts +141 -0
- package/src/domain/mcpserver/connect.ts +21 -82
- package/src/domain/plugin/overlay/sanitize.ts +2 -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 +9 -235
- package/src/domain/workflowexecution/create-steps.ts +4 -3
- package/src/pipeline/apiresource-labels.ts +2 -2
- package/src/pipeline/errors.ts +2 -2
- package/src/pipeline/steps/guard-reserved-labels.ts +6 -5
- 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
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The session run-target resolver (P1 sp.run-gate): a session
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* The session run-target resolver (P1 sp.run-gate): a session bound to an
|
|
3
|
+
* agent instance has that instance as its run target —
|
|
4
|
+
* agent_instance#can_execute on spec.agent_instance_id.
|
|
5
5
|
*
|
|
6
|
-
* Pure over the record being built.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Pure over the record being built. An empty id is the built-in assistant
|
|
7
|
+
* (session/v1/spec.proto): there is no blueprint to spend, so the answer is
|
|
8
|
+
* "no target" and the gate makes no check. What admits the conversation is
|
|
9
|
+
* the Authorize step ahead of the gate — can_create_session on the
|
|
10
|
+
* organization — and each turn is admitted by the session's own
|
|
11
|
+
* can_create_execution_in on the execution chain.
|
|
11
12
|
*/
|
|
12
13
|
import type { Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
|
|
13
14
|
|
|
@@ -6,22 +6,22 @@
|
|
|
6
6
|
* record_harness_state_history.go) and its steps/ package
|
|
7
7
|
* (filter_by_agent_instance.go, filter_by_channel.go). Shared steps stay
|
|
8
8
|
* in src/pipeline/steps/; these exist because they embody
|
|
9
|
-
* session-specific contracts: the
|
|
10
|
-
* harness
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* session-specific contracts: the harness/execution-target immutability
|
|
10
|
+
* sentinels, the server-owned harness-state history, the active-execution
|
|
11
|
+
* delete guard with its execution cascade, and the list filters.
|
|
12
|
+
*
|
|
13
|
+
* An empty spec.agent_instance_id is a legal shape and stays empty: the
|
|
14
|
+
* session runs the built-in assistant (session/v1/spec.proto). No step here
|
|
15
|
+
* resolves it into an instance, and no step guards it on update, because
|
|
16
|
+
* a conversation may gain an agent or drop back to the assistant; the
|
|
17
|
+
* immutable fields are the harness and the execution target below.
|
|
13
18
|
*/
|
|
14
|
-
import { Code, ConnectError } from "@connectrpc/connect";
|
|
15
19
|
import { create, fromBinary } from "@bufbuild/protobuf";
|
|
16
20
|
import type { DescMessage } from "@bufbuild/protobuf";
|
|
17
21
|
|
|
18
|
-
import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
19
|
-
import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
20
|
-
import { AgentStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/status_pb";
|
|
21
22
|
import { AgentExecutionSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
22
23
|
import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
23
24
|
import { ExecutionPhase } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
24
|
-
import type { AgentInstance } from "@stigmer/protos/ai/stigmer/agentic/agentinstance/v1/api_pb";
|
|
25
25
|
import { SessionSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
|
|
26
26
|
import type { Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
|
|
27
27
|
import {
|
|
@@ -30,7 +30,6 @@ import {
|
|
|
30
30
|
} from "@stigmer/protos/ai/stigmer/agentic/session/v1/enum_pb";
|
|
31
31
|
import { SessionListSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/io_pb";
|
|
32
32
|
import { SessionQueryController } from "@stigmer/protos/ai/stigmer/agentic/session/v1/query_pb";
|
|
33
|
-
import { SessionSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/spec_pb";
|
|
34
33
|
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
35
34
|
import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
36
35
|
|
|
@@ -38,29 +37,19 @@ import type { Logger } from "../../boot/logger.js";
|
|
|
38
37
|
import type { AgentExecutionTemporalConfig } from "../agentexecution/temporal/config.js";
|
|
39
38
|
import {
|
|
40
39
|
failedPreconditionError,
|
|
41
|
-
goWrappedStatusError,
|
|
42
40
|
internalError,
|
|
43
41
|
invalidArgumentError,
|
|
44
42
|
} from "../../pipeline/errors.js";
|
|
45
43
|
import type { PipelineStep } from "../../pipeline/pipeline.js";
|
|
46
|
-
import type { CallerIdentity } from "../../extensions/identity.js";
|
|
47
44
|
import type { Authorizer } from "../../extensions/authorizer.js";
|
|
48
45
|
import type { ListReadScope } from "../../extensions/list-read-scope.js";
|
|
49
46
|
import { restrictListByReadScope } from "../../extensions/list-read-scope.js";
|
|
50
|
-
import type { ResourceAuthorizationLifecycle } from "../../extensions/resource-authorization.js";
|
|
51
47
|
import { authorizeResolvedResource } from "../../pipeline/steps/authorize.js";
|
|
52
|
-
import { notifyDefaultInstanceLinked } from "../../pipeline/steps/authorization-tuples.js";
|
|
53
48
|
import type { RequestContext } from "../../pipeline/request-context.js";
|
|
54
49
|
import { RESOURCE_ID_KEY } from "../../pipeline/steps/delete.js";
|
|
55
50
|
import { compareCreatedAtDesc } from "../../pipeline/steps/helpers.js";
|
|
56
51
|
import { EXISTING_RESOURCE_KEY } from "../../pipeline/steps/load-existing.js";
|
|
57
52
|
import type { Store } from "../../store/interface.js";
|
|
58
|
-
import { buildDefaultInstanceRequest } from "../agentinstance/defaultinstance.js";
|
|
59
|
-
import {
|
|
60
|
-
DefaultAgentNotConfiguredError,
|
|
61
|
-
DefaultAgentNotPublicError,
|
|
62
|
-
findDefaultAgent,
|
|
63
|
-
} from "../agent/defaultagent.js";
|
|
64
53
|
|
|
65
54
|
type SessionDesc = typeof SessionSchema;
|
|
66
55
|
|
|
@@ -74,221 +63,6 @@ export const LIST_RESULT_KEY = "listResult";
|
|
|
74
63
|
*/
|
|
75
64
|
const CHANNEL_ID_LABEL_KEY = "stigmer.ai/channel-id";
|
|
76
65
|
|
|
77
|
-
/**
|
|
78
|
-
* The narrow in-process surface the session domain needs from
|
|
79
|
-
* agentinstance — consumer-defined so the dependency reads at the domain
|
|
80
|
-
* boundary (the Go twin is pkg/downstream/agentinstance.Client). This is
|
|
81
|
-
* the CREATE RPC (Go CreateAsSystem), not apply: the resolve step only
|
|
82
|
-
* reaches it when the default instance is known to be missing, and a
|
|
83
|
-
* duplicate-slug collision must surface as AlreadyExists, not silently
|
|
84
|
-
* update. Calls ride the in-process router transport, traversing the full
|
|
85
|
-
* interceptor chain (DD-002).
|
|
86
|
-
*/
|
|
87
|
-
export interface AgentInstanceCreator {
|
|
88
|
-
/**
|
|
89
|
-
* Creates AS THE ORIGINAL CALLER (C2 Stage 3, ruling R5 — the Java
|
|
90
|
-
* createAsCaller posture): the propagated identity gives the created
|
|
91
|
-
* instance real owner attribution under an enforcing Authorizer.
|
|
92
|
-
*/
|
|
93
|
-
createAsCaller(
|
|
94
|
-
instance: AgentInstance,
|
|
95
|
-
caller: CallerIdentity,
|
|
96
|
-
): Promise<AgentInstance>;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Lazy provider for the in-process agentinstance edge — resolved at call
|
|
101
|
-
* time, never at construction (the ratified DI story, D2 §2).
|
|
102
|
-
*/
|
|
103
|
-
export type AgentInstanceCreatorProvider = () => AgentInstanceCreator;
|
|
104
|
-
|
|
105
|
-
// ---------------------------------------------------------------------------
|
|
106
|
-
// ResolveDefaultAgentInstance — create.go:62-182: when agent_instance_id is
|
|
107
|
-
// not provided, resolve the platform default agent (shared defaultagent
|
|
108
|
-
// implementation: label stigmer.ai/default-agent=true, visibility_public,
|
|
109
|
-
// deterministic incumbent-wins tie-break), get or create its default
|
|
110
|
-
// instance, and set agent_instance_id on the session spec. This enables the
|
|
111
|
-
// session-first UX where users create a session (with workspace entries)
|
|
112
|
-
// without knowing the agent instance — the backend resolves it
|
|
113
|
-
// automatically.
|
|
114
|
-
//
|
|
115
|
-
// Runs FIRST in the create chain, before ValidateProto — resolution must
|
|
116
|
-
// fill agent_instance_id before validation sees the spec.
|
|
117
|
-
//
|
|
118
|
-
// The id lands on ctx.newState.spec, NEVER on input: the pipeline cloned
|
|
119
|
-
// input into newState at construction and Persist saves newState, so
|
|
120
|
-
// mutating input does not propagate (Go's documented clone gotcha,
|
|
121
|
-
// create.go:168-170).
|
|
122
|
-
// ---------------------------------------------------------------------------
|
|
123
|
-
|
|
124
|
-
export function newResolveDefaultAgentInstanceStep(
|
|
125
|
-
store: Store,
|
|
126
|
-
creator: AgentInstanceCreatorProvider,
|
|
127
|
-
logger: Logger,
|
|
128
|
-
authorizationLifecycle?: ResourceAuthorizationLifecycle,
|
|
129
|
-
): PipelineStep<SessionDesc> {
|
|
130
|
-
return {
|
|
131
|
-
name: "ResolveDefaultAgentInstance",
|
|
132
|
-
async execute(ctx: RequestContext<SessionDesc>): Promise<void> {
|
|
133
|
-
if ((ctx.input.spec?.agentInstanceId ?? "") !== "") {
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
logger.info(
|
|
138
|
-
"agent_instance_id not provided on session, resolving platform default agent",
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
// 1. Resolve the default agent. The error copy is Go WrapError's
|
|
142
|
-
// "%s: %v" — the sentinel's text RIDES the wire message, and the
|
|
143
|
-
// NotFound arm carries Go's DOUBLE wrap (fmt.Errorf("no default
|
|
144
|
-
// agent available on this platform: %w", err) inside WrapError).
|
|
145
|
-
// Byte-pinned.
|
|
146
|
-
let defaultAgent: Agent;
|
|
147
|
-
try {
|
|
148
|
-
defaultAgent = await findDefaultAgent(store, logger);
|
|
149
|
-
} catch (error) {
|
|
150
|
-
if (error instanceof DefaultAgentNotConfiguredError) {
|
|
151
|
-
logger.error("No platform default agent configured", {
|
|
152
|
-
error: error.message,
|
|
153
|
-
});
|
|
154
|
-
throw new ConnectError(
|
|
155
|
-
`No default agent available. Ensure an agent with label stigmer.ai/default-agent=true and visibility_public exists: no default agent available on this platform: ${error.message}`,
|
|
156
|
-
Code.NotFound,
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
if (error instanceof DefaultAgentNotPublicError) {
|
|
160
|
-
logger.error("Default agent is not visibility_public", {
|
|
161
|
-
error: error.message,
|
|
162
|
-
});
|
|
163
|
-
throw new ConnectError(
|
|
164
|
-
`Default agent exists but is not visibility_public: ${error.message}`,
|
|
165
|
-
Code.FailedPrecondition,
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
// Store/decode failure — an internal fault, not "no default
|
|
169
|
-
// agent". InternalError keeps the cause off the wire
|
|
170
|
-
// (stigmer/stigmer#478).
|
|
171
|
-
logger.error("Failed to resolve platform default agent", {
|
|
172
|
-
error: error instanceof Error ? error.message : String(error),
|
|
173
|
-
});
|
|
174
|
-
throw internalError(
|
|
175
|
-
error,
|
|
176
|
-
"failed to resolve the platform default agent",
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const metadata = defaultAgent.metadata;
|
|
181
|
-
if (metadata === undefined) {
|
|
182
|
-
// Unreachable: findDefaultAgent only returns public-visibility
|
|
183
|
-
// candidates, whose metadata is necessarily set.
|
|
184
|
-
throw internalError(
|
|
185
|
-
new Error("default agent metadata is nil"),
|
|
186
|
-
"failed to resolve the platform default agent",
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
const agentId = metadata.id;
|
|
190
|
-
logger.info("Resolved platform default agent", {
|
|
191
|
-
agentId,
|
|
192
|
-
agentName: metadata.name,
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
// 2. Get or create the default instance.
|
|
196
|
-
let defaultInstanceId = defaultAgent.status?.defaultInstanceId ?? "";
|
|
197
|
-
if (defaultInstanceId === "") {
|
|
198
|
-
logger.info("Default instance missing, creating one", { agentId });
|
|
199
|
-
|
|
200
|
-
const instanceRequest = buildDefaultInstanceRequest(metadata);
|
|
201
|
-
|
|
202
|
-
// Go create.go:144-148 wraps the downstream error with fmt.Errorf
|
|
203
|
-
// ("failed to create default instance for default agent: %w") and
|
|
204
|
-
// PipelineError.GRPCStatus's errors.As branch keeps the inner
|
|
205
|
-
// CODE but rewrites the wire MESSAGE to the wrapped text —
|
|
206
|
-
// transport formatting (`rpc error: code = X desc = ...`)
|
|
207
|
-
// included. Mirrored byte-for-byte via goWrappedStatusError; the
|
|
208
|
-
// leak is stigmer/stigmer#852 (both-editions post-cutover fix).
|
|
209
|
-
// Unstatused failures fall to the pipeline's Internal fallback,
|
|
210
|
-
// exactly Go's plain-error path.
|
|
211
|
-
let createdInstance: AgentInstance;
|
|
212
|
-
try {
|
|
213
|
-
createdInstance = await creator().createAsCaller(
|
|
214
|
-
instanceRequest,
|
|
215
|
-
ctx.callerIdentity,
|
|
216
|
-
);
|
|
217
|
-
} catch (error) {
|
|
218
|
-
logger.error("Failed to create default instance", {
|
|
219
|
-
agentId,
|
|
220
|
-
error: error instanceof Error ? error.message : String(error),
|
|
221
|
-
});
|
|
222
|
-
if (error instanceof ConnectError) {
|
|
223
|
-
throw goWrappedStatusError(
|
|
224
|
-
"failed to create default instance for default agent",
|
|
225
|
-
error,
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
throw new Error(
|
|
229
|
-
`failed to create default instance for default agent: ${error instanceof Error ? error.message : String(error)}`,
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
defaultInstanceId = createdInstance.metadata?.id ?? "";
|
|
234
|
-
|
|
235
|
-
// Persist default_instance_id on the agent — EXPLICITLY the agent
|
|
236
|
-
// kind: this pipeline's ctx kind is session (Go hardcodes
|
|
237
|
-
// ApiResourceKind_agent here too).
|
|
238
|
-
if (defaultAgent.status === undefined) {
|
|
239
|
-
defaultAgent.status = create(AgentStatusSchema, {});
|
|
240
|
-
}
|
|
241
|
-
defaultAgent.status.defaultInstanceId = defaultInstanceId;
|
|
242
|
-
try {
|
|
243
|
-
await store.saveResource(
|
|
244
|
-
ApiResourceKind.agent,
|
|
245
|
-
agentId,
|
|
246
|
-
AgentSchema,
|
|
247
|
-
defaultAgent,
|
|
248
|
-
);
|
|
249
|
-
} catch (error) {
|
|
250
|
-
logger.error("Failed to persist agent with default_instance_id", {
|
|
251
|
-
agentId,
|
|
252
|
-
error: error instanceof Error ? error.message : String(error),
|
|
253
|
-
});
|
|
254
|
-
// Go wraps as a plain error → the pipeline's Internal fallback.
|
|
255
|
-
throw new Error(
|
|
256
|
-
`failed to persist agent with default instance: ${error instanceof Error ? error.message : String(error)}`,
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// The default_of invariant rides the pointer persist (C2 Stage 3).
|
|
261
|
-
await notifyDefaultInstanceLinked(authorizationLifecycle, {
|
|
262
|
-
instanceKind: ApiResourceKind.agent_instance,
|
|
263
|
-
instanceId: defaultInstanceId,
|
|
264
|
-
blueprintKind: ApiResourceKind.agent,
|
|
265
|
-
blueprintId: agentId,
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
logger.info("Created default instance for default agent", {
|
|
269
|
-
instanceId: defaultInstanceId,
|
|
270
|
-
agentId,
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// 3. Set agent_instance_id on the session's newState (not input) —
|
|
275
|
-
// see the module-level clone gotcha note.
|
|
276
|
-
const newState = ctx.newState;
|
|
277
|
-
if (newState.spec === undefined) {
|
|
278
|
-
newState.spec = create(SessionSpecSchema, {});
|
|
279
|
-
}
|
|
280
|
-
newState.spec.agentInstanceId = defaultInstanceId;
|
|
281
|
-
|
|
282
|
-
logger.info(
|
|
283
|
-
"Set agent_instance_id on session from platform default agent",
|
|
284
|
-
{
|
|
285
|
-
agentInstanceId: defaultInstanceId,
|
|
286
|
-
},
|
|
287
|
-
);
|
|
288
|
-
},
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
|
|
292
66
|
// ---------------------------------------------------------------------------
|
|
293
67
|
// ValidateHarnessImmutability — validate_harness_immutability.go: rejects
|
|
294
68
|
// session updates that attempt to change the harness after the session has
|
|
@@ -62,9 +62,10 @@ export type ExecutionWorkflowInstanceCreatorProvider =
|
|
|
62
62
|
/**
|
|
63
63
|
* ValidateWorkflowOrInstance — at least one of workflow_id /
|
|
64
64
|
* workflow_instance_id must be provided. Matches the cloud
|
|
65
|
-
* WorkflowExecutionCreateHandler. AgentExecution differs
|
|
66
|
-
*
|
|
67
|
-
*
|
|
65
|
+
* WorkflowExecutionCreateHandler. AgentExecution differs on purpose: its
|
|
66
|
+
* all-empty shape is legal (the built-in assistant), so it has no such
|
|
67
|
+
* step; a workflow execution has no built-in workflow to fall back to
|
|
68
|
+
* (issue #196).
|
|
68
69
|
*/
|
|
69
70
|
export function newValidateWorkflowOrInstanceStep(): PipelineStep<ExecutionDesc> {
|
|
70
71
|
return {
|
|
@@ -23,8 +23,8 @@ import type { ApiResourceMetadata } from "@stigmer/protos/ai/stigmer/commons/api
|
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* The platform-reserved label key namespace. Keys under this prefix carry
|
|
26
|
-
* platform semantics (
|
|
27
|
-
*
|
|
26
|
+
* platform semantics (personal-environment uniqueness, default-instance
|
|
27
|
+
* marking, plugin membership and lineage) and are written by the server —
|
|
28
28
|
* never introduced by ordinary client requests on the cloud edition.
|
|
29
29
|
*/
|
|
30
30
|
export const RESERVED_LABEL_PREFIX = "stigmer.ai/";
|
package/src/pipeline/errors.ts
CHANGED
|
@@ -100,8 +100,8 @@ export function grpcCodeName(code: Code): string {
|
|
|
100
100
|
* errors.As branch keeps the INNER code but rewrites the message to the
|
|
101
101
|
* full wrapped text — and the inner client error's Error() renders as
|
|
102
102
|
* `rpc error: code = <CodeName> desc = <message>`. Byte-parity with Go on
|
|
103
|
-
* the
|
|
104
|
-
*
|
|
103
|
+
* the arms that hit this (agent create's CreateDefaultInstance, agent
|
|
104
|
+
* execution create's default-instance and session bootstrap). The transport-formatting
|
|
105
105
|
* leak is filed as stigmer/stigmer#852 for a both-editions post-cutover
|
|
106
106
|
* fix; until then this shim IS the wire contract.
|
|
107
107
|
*
|
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
* `stigmer.ai/*` label namespace (the Java GuardReservedLabelsStep port,
|
|
4
4
|
* cloud#320/#386; C2 Stage 3, 20260827.10).
|
|
5
5
|
*
|
|
6
|
-
* Reserved labels carry platform semantics
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Reserved labels carry platform semantics the server reads and acts on
|
|
7
|
+
* (the personal-environment marker, the default-instance marker, the
|
|
8
|
+
* membership and lineage labels): a client that could write one would be
|
|
9
|
+
* writing a platform decision, and any reader trusting the label would be
|
|
10
|
+
* trusting the client. Only rejecting the write closes that; the label is
|
|
11
|
+
* not authorization, the server is.
|
|
11
12
|
*
|
|
12
13
|
* Behavior (the Java matrix verbatim):
|
|
13
14
|
* - ECHOES pass — clients read-modify-write whole resources, so a
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
2
|
-
import type { Logger } from "../../boot/logger.js";
|
|
3
|
-
import type { Store } from "../../store/interface.js";
|
|
4
|
-
/** Marks the platform default agent; the value must be DEFAULT_AGENT_LABEL_VALUE. */
|
|
5
|
-
export declare const DEFAULT_AGENT_LABEL = "stigmer.ai/default-agent";
|
|
6
|
-
/** The only value of DEFAULT_AGENT_LABEL that marks an agent as the default. */
|
|
7
|
-
export declare const DEFAULT_AGENT_LABEL_VALUE = "true";
|
|
8
|
-
/**
|
|
9
|
-
* No agent carries the default-agent label. Call sites map this to
|
|
10
|
-
* NotFound with their own caller-facing copy (Go ErrNotConfigured).
|
|
11
|
-
*/
|
|
12
|
-
export declare class DefaultAgentNotConfiguredError extends Error {
|
|
13
|
-
constructor();
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Labeled agents exist but none is visibility_public. Call sites map this
|
|
17
|
-
* to FailedPrecondition — a deliberate divergence from the cloud edition,
|
|
18
|
-
* whose SQL predicate collapses this state into "not found": the distinct
|
|
19
|
-
* code tells a self-hosting operator the label is present but the
|
|
20
|
-
* visibility is wrong (Go ErrNotPublic).
|
|
21
|
-
*/
|
|
22
|
-
export declare class DefaultAgentNotPublicError extends Error {
|
|
23
|
-
constructor();
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Resolves the platform default agent per the module contract: candidates
|
|
27
|
-
* are all agents labeled DEFAULT_AGENT_LABEL=true, only visibility_public
|
|
28
|
-
* candidates are eligible, and among those the lowest metadata.id wins.
|
|
29
|
-
*
|
|
30
|
-
* Throws DefaultAgentNotConfiguredError when nothing carries the label,
|
|
31
|
-
* DefaultAgentNotPublicError when labeled agents exist but none is public,
|
|
32
|
-
* and lets store/decode failures propagate (a store failure is an internal
|
|
33
|
-
* fault, not a "no default agent" condition — callers must not map it to
|
|
34
|
-
* NotFound).
|
|
35
|
-
*/
|
|
36
|
-
export declare function findDefaultAgent(store: Store, logger: Logger): Promise<Agent>;
|
|
37
|
-
//# sourceMappingURL=defaultagent.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"defaultagent.d.ts","sourceRoot":"","sources":["../../../src/domain/agent/defaultagent.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oDAAoD,CAAC;AAIhF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAEtD,qFAAqF;AACrF,eAAO,MAAM,mBAAmB,6BAA6B,CAAC;AAE9D,gFAAgF;AAChF,eAAO,MAAM,yBAAyB,SAAS,CAAC;AAEhD;;;GAGG;AACH,qBAAa,8BAA+B,SAAQ,KAAK;;CAOxD;AAED;;;;;;GAMG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;;CAOpD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,KAAK,CAAC,CAkDhB"}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Platform default-agent resolution — ports
|
|
3
|
-
* pkg/domain/agent/defaultagent/defaultagent.go: the single resolution
|
|
4
|
-
* implementation behind Agent.GetDefault, AgentExecution create (#17), and
|
|
5
|
-
* Session create.
|
|
6
|
-
*
|
|
7
|
-
* The default agent is a platform-level singleton: the agent labeled
|
|
8
|
-
* stigmer.ai/default-agent: "true" with visibility_public, seeded in the
|
|
9
|
-
* system org and served to callers of every org. Resolution is deliberately
|
|
10
|
-
* GLOBAL — GetDefaultAgentRequest.org exists for authorization scoping only
|
|
11
|
-
* (see apis/ai/stigmer/agentic/agent/v1/io.proto). It powers the
|
|
12
|
-
* session-first UX where a user starts a conversation without picking an
|
|
13
|
-
* agent. The cloud twin is AgentRepo.findDefault(); keep the two in sync.
|
|
14
|
-
*
|
|
15
|
-
* Determinism contract (stigmer/stigmer#356): multiple labeled agents is a
|
|
16
|
-
* reachable state, not an error — safe label rotation applies the new
|
|
17
|
-
* default before retiring the old one. Among public candidates the winner
|
|
18
|
-
* is the one with the LOWEST metadata.id — the incumbent. Rejected
|
|
19
|
-
* alternatives (recorded in the Go package doc): first-match depends on row
|
|
20
|
-
* insertion order; newest-wins lets any newly labeled public agent capture
|
|
21
|
-
* the platform-wide default (nothing guards the reserved stigmer.ai/*
|
|
22
|
-
* namespace at OSS write boundaries); creation time is not trustworthy as
|
|
23
|
-
* an ordering key (pre-#453 rows may carry rewritten timestamps).
|
|
24
|
-
* metadata.id never changes and is time-ordered for server-generated ULIDs.
|
|
25
|
-
*/
|
|
26
|
-
import { fromBinary } from "@bufbuild/protobuf";
|
|
27
|
-
import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
28
|
-
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
|
|
29
|
-
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
30
|
-
/** Marks the platform default agent; the value must be DEFAULT_AGENT_LABEL_VALUE. */
|
|
31
|
-
export const DEFAULT_AGENT_LABEL = "stigmer.ai/default-agent";
|
|
32
|
-
/** The only value of DEFAULT_AGENT_LABEL that marks an agent as the default. */
|
|
33
|
-
export const DEFAULT_AGENT_LABEL_VALUE = "true";
|
|
34
|
-
/**
|
|
35
|
-
* No agent carries the default-agent label. Call sites map this to
|
|
36
|
-
* NotFound with their own caller-facing copy (Go ErrNotConfigured).
|
|
37
|
-
*/
|
|
38
|
-
export class DefaultAgentNotConfiguredError extends Error {
|
|
39
|
-
constructor() {
|
|
40
|
-
super(`no agent labeled ${DEFAULT_AGENT_LABEL}=${DEFAULT_AGENT_LABEL_VALUE}`);
|
|
41
|
-
this.name = "DefaultAgentNotConfiguredError";
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Labeled agents exist but none is visibility_public. Call sites map this
|
|
46
|
-
* to FailedPrecondition — a deliberate divergence from the cloud edition,
|
|
47
|
-
* whose SQL predicate collapses this state into "not found": the distinct
|
|
48
|
-
* code tells a self-hosting operator the label is present but the
|
|
49
|
-
* visibility is wrong (Go ErrNotPublic).
|
|
50
|
-
*/
|
|
51
|
-
export class DefaultAgentNotPublicError extends Error {
|
|
52
|
-
constructor() {
|
|
53
|
-
super(`agents labeled ${DEFAULT_AGENT_LABEL}=${DEFAULT_AGENT_LABEL_VALUE} exist but none is visibility_public`);
|
|
54
|
-
this.name = "DefaultAgentNotPublicError";
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Resolves the platform default agent per the module contract: candidates
|
|
59
|
-
* are all agents labeled DEFAULT_AGENT_LABEL=true, only visibility_public
|
|
60
|
-
* candidates are eligible, and among those the lowest metadata.id wins.
|
|
61
|
-
*
|
|
62
|
-
* Throws DefaultAgentNotConfiguredError when nothing carries the label,
|
|
63
|
-
* DefaultAgentNotPublicError when labeled agents exist but none is public,
|
|
64
|
-
* and lets store/decode failures propagate (a store failure is an internal
|
|
65
|
-
* fault, not a "no default agent" condition — callers must not map it to
|
|
66
|
-
* NotFound).
|
|
67
|
-
*/
|
|
68
|
-
export async function findDefaultAgent(store, logger) {
|
|
69
|
-
const raws = await store.findAllByLabel(ApiResourceKind.agent, DEFAULT_AGENT_LABEL, DEFAULT_AGENT_LABEL_VALUE, AgentSchema);
|
|
70
|
-
if (raws.length === 0) {
|
|
71
|
-
throw new DefaultAgentNotConfiguredError();
|
|
72
|
-
}
|
|
73
|
-
let publicCount = 0;
|
|
74
|
-
let winner;
|
|
75
|
-
for (const raw of raws) {
|
|
76
|
-
// findAllByLabel already unmarshaled every returned row to match the
|
|
77
|
-
// label, so a decode failure here is store corruption. Fail loudly
|
|
78
|
-
// (propagate): skipping a row could silently change which agent wins.
|
|
79
|
-
const candidate = fromBinary(AgentSchema, raw);
|
|
80
|
-
if (candidate.metadata?.visibility !==
|
|
81
|
-
ApiResourceVisibility.visibility_public) {
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
publicCount++;
|
|
85
|
-
if (winner === undefined ||
|
|
86
|
-
(candidate.metadata?.id ?? "") < (winner.metadata?.id ?? "")) {
|
|
87
|
-
winner = candidate;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
if (winner === undefined) {
|
|
91
|
-
throw new DefaultAgentNotPublicError();
|
|
92
|
-
}
|
|
93
|
-
if (publicCount > 1) {
|
|
94
|
-
// Expected briefly mid-rotation; persistent duplicates mean someone
|
|
95
|
-
// forgot to retire the old label after applying the new default.
|
|
96
|
-
logger.warn("Multiple public agents carry the default-agent label; serving the incumbent (lowest id). Retire the stale label to complete rotation.", {
|
|
97
|
-
publicLabeledAgents: publicCount,
|
|
98
|
-
winnerId: winner.metadata?.id ?? "",
|
|
99
|
-
winnerName: winner.metadata?.name ?? "",
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
return winner;
|
|
103
|
-
}
|
|
104
|
-
//# sourceMappingURL=defaultagent.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"defaultagent.js","sourceRoot":"","sources":["../../../src/domain/agent/defaultagent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AAEjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,wDAAwD,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,MAAM,qFAAqF,CAAC;AAKtH,qFAAqF;AACrF,MAAM,CAAC,MAAM,mBAAmB,GAAG,0BAA0B,CAAC;AAE9D,gFAAgF;AAChF,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAEhD;;;GAGG;AACH,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IACvD;QACE,KAAK,CACH,oBAAoB,mBAAmB,IAAI,yBAAyB,EAAE,CACvE,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;IAC/C,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnD;QACE,KAAK,CACH,kBAAkB,mBAAmB,IAAI,yBAAyB,sCAAsC,CACzG,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAY,EACZ,MAAc;IAEd,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,cAAc,CACrC,eAAe,CAAC,KAAK,EACrB,mBAAmB,EACnB,yBAAyB,EACzB,WAAW,CACZ,CAAC;IACF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,8BAA8B,EAAE,CAAC;IAC7C,CAAC;IAED,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,MAAyB,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,qEAAqE;QACrE,mEAAmE;QACnE,sEAAsE;QACtE,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAC/C,IACE,SAAS,CAAC,QAAQ,EAAE,UAAU;YAC9B,qBAAqB,CAAC,iBAAiB,EACvC,CAAC;YACD,SAAS;QACX,CAAC;QACD,WAAW,EAAE,CAAC;QACd,IACE,MAAM,KAAK,SAAS;YACpB,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,EAC5D,CAAC;YACD,MAAM,GAAG,SAAS,CAAC;QACrB,CAAC;IACH,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,0BAA0B,EAAE,CAAC;IACzC,CAAC;IAED,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACpB,oEAAoE;QACpE,iEAAiE;QACjE,MAAM,CAAC,IAAI,CACT,uIAAuI,EACvI;YACE,mBAAmB,EAAE,WAAW;YAChC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE;YACnC,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE;SACxC,CACF,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|