@namzu/sdk 12.2.0 → 13.1.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/CHANGELOG.md +199 -0
- package/dist/bridge/a2a/__tests__/project-is-the-a2a-context.test.d.ts +2 -0
- package/dist/bridge/a2a/__tests__/project-is-the-a2a-context.test.d.ts.map +1 -0
- package/dist/bridge/a2a/__tests__/project-is-the-a2a-context.test.js +55 -0
- package/dist/bridge/a2a/__tests__/project-is-the-a2a-context.test.js.map +1 -0
- package/dist/manager/agent/__tests__/an-env-reaches-the-child-it-was-set-for.test.d.ts +2 -0
- package/dist/manager/agent/__tests__/an-env-reaches-the-child-it-was-set-for.test.d.ts.map +1 -0
- package/dist/manager/agent/__tests__/an-env-reaches-the-child-it-was-set-for.test.js +159 -0
- package/dist/manager/agent/__tests__/an-env-reaches-the-child-it-was-set-for.test.js.map +1 -0
- package/dist/manager/agent/lifecycle.d.ts +15 -0
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +103 -26
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/public-runtime.d.ts +1 -1
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +7 -1
- package/dist/public-runtime.js.map +1 -1
- package/dist/session/__tests__/integration/a-successful-delegation-disposes-its-workspace.test.d.ts +21 -0
- package/dist/session/__tests__/integration/a-successful-delegation-disposes-its-workspace.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/a-successful-delegation-disposes-its-workspace.test.js +205 -0
- package/dist/session/__tests__/integration/a-successful-delegation-disposes-its-workspace.test.js.map +1 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.js +14 -5
- package/dist/session/__tests__/integration/handoff-single-e2e.test.js.map +1 -1
- package/dist/session/errors.d.ts +25 -0
- package/dist/session/errors.d.ts.map +1 -1
- package/dist/session/errors.js +21 -0
- package/dist/session/errors.js.map +1 -1
- package/dist/session/handoff/broadcast.d.ts.map +1 -1
- package/dist/session/handoff/broadcast.js +10 -5
- package/dist/session/handoff/broadcast.js.map +1 -1
- package/dist/session/handoff/single.d.ts.map +1 -1
- package/dist/session/handoff/single.js +27 -4
- package/dist/session/handoff/single.js.map +1 -1
- package/dist/store/session/__tests__/a-session-has-one-writer.test.d.ts +2 -0
- package/dist/store/session/__tests__/a-session-has-one-writer.test.d.ts.map +1 -0
- package/dist/store/session/__tests__/a-session-has-one-writer.test.js +79 -0
- package/dist/store/session/__tests__/a-session-has-one-writer.test.js.map +1 -0
- package/dist/store/session/__tests__/a-workspace-can-be-configured.test.d.ts +2 -0
- package/dist/store/session/__tests__/a-workspace-can-be-configured.test.d.ts.map +1 -0
- package/dist/store/session/__tests__/a-workspace-can-be-configured.test.js +149 -0
- package/dist/store/session/__tests__/a-workspace-can-be-configured.test.js.map +1 -0
- package/dist/store/session/disk.d.ts +4 -2
- package/dist/store/session/disk.d.ts.map +1 -1
- package/dist/store/session/disk.js +71 -4
- package/dist/store/session/disk.js.map +1 -1
- package/dist/store/session/memory.d.ts +4 -2
- package/dist/store/session/memory.d.ts.map +1 -1
- package/dist/store/session/memory.js +53 -4
- package/dist/store/session/memory.js.map +1 -1
- package/dist/tools/coordinator/agent.d.ts.map +1 -1
- package/dist/tools/coordinator/agent.js +7 -0
- package/dist/tools/coordinator/agent.js.map +1 -1
- package/dist/tools/coordinator/index.d.ts.map +1 -1
- package/dist/tools/coordinator/index.js +6 -0
- package/dist/tools/coordinator/index.js.map +1 -1
- package/dist/types/agent/base.d.ts +22 -0
- package/dist/types/agent/base.d.ts.map +1 -1
- package/dist/types/session/store.d.ts +80 -1
- package/dist/types/session/store.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/bridge/a2a/__tests__/project-is-the-a2a-context.test.ts +66 -0
- package/src/manager/agent/__tests__/an-env-reaches-the-child-it-was-set-for.test.ts +196 -0
- package/src/manager/agent/lifecycle.ts +107 -26
- package/src/public-runtime.ts +6 -0
- package/src/session/__tests__/integration/a-successful-delegation-disposes-its-workspace.test.ts +270 -0
- package/src/session/__tests__/integration/handoff-single-e2e.test.ts +14 -5
- package/src/session/errors.ts +29 -0
- package/src/session/handoff/broadcast.ts +10 -5
- package/src/session/handoff/single.ts +27 -4
- package/src/store/session/__tests__/a-session-has-one-writer.test.ts +116 -0
- package/src/store/session/__tests__/a-workspace-can-be-configured.test.ts +210 -0
- package/src/store/session/disk.ts +84 -4
- package/src/store/session/memory.ts +66 -4
- package/src/tools/coordinator/agent.ts +7 -0
- package/src/tools/coordinator/index.ts +6 -0
- package/src/types/agent/base.ts +23 -0
- package/src/types/session/store.ts +88 -1
|
@@ -146,6 +146,13 @@ export function buildAgentTool(opts: AgentToolOptions): ToolDefinition {
|
|
|
146
146
|
// surface, and the one it exports as the canonical shape —
|
|
147
147
|
// did not.
|
|
148
148
|
...(context.parentSpan ? { parentSpan: context.parentSpan } : {}),
|
|
149
|
+
// The parent's environment, which is the whole point of setting
|
|
150
|
+
// one: a delegate that cannot see it runs against different
|
|
151
|
+
// services than the run that launched it, silently.
|
|
152
|
+
// `ToolContext.env` is the parent's own resolved map, per run.
|
|
153
|
+
...(Object.keys(context.env ?? {}).length > 0
|
|
154
|
+
? { configOverrides: { env: context.env } }
|
|
155
|
+
: {}),
|
|
149
156
|
})
|
|
150
157
|
|
|
151
158
|
onTaskLaunched?.(handle.taskId, {
|
|
@@ -484,6 +484,12 @@ export function buildCoordinatorTools(opts: CoordinatorToolsOptions): ToolDefini
|
|
|
484
484
|
// Hang the child run off THIS tool's span, so the delegation
|
|
485
485
|
// shows up inside the turn that asked for it.
|
|
486
486
|
...(_context.parentSpan ? { parentSpan: _context.parentSpan } : {}),
|
|
487
|
+
// Same as the `Agent` tool: a delegate inherits the environment
|
|
488
|
+
// its parent was given, or it runs against different services
|
|
489
|
+
// than the run that asked for the work.
|
|
490
|
+
...(Object.keys(_context.env ?? {}).length > 0
|
|
491
|
+
? { configOverrides: { env: _context.env } }
|
|
492
|
+
: {}),
|
|
487
493
|
})
|
|
488
494
|
|
|
489
495
|
// Whose task this is. The inbox ignores completions for anything it
|
package/src/types/agent/base.ts
CHANGED
|
@@ -22,6 +22,29 @@ export interface BaseAgentConfig {
|
|
|
22
22
|
maxResponseTokens?: number
|
|
23
23
|
costLimitUsd?: number
|
|
24
24
|
permissionMode?: PermissionMode
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Extra environment variables for this agent's tools and sandboxed
|
|
28
|
+
* commands, merged over whatever ambient environment the execution path
|
|
29
|
+
* supplies. Inherited by every delegated descendant.
|
|
30
|
+
*
|
|
31
|
+
* **Configuration, not credentials** — and that is a property of the
|
|
32
|
+
* CHANNEL rather than a judgement about any particular value. This map is
|
|
33
|
+
* copied into every child, is readable by any tool that can run a command,
|
|
34
|
+
* and enters a model's context and the run transcript the moment something
|
|
35
|
+
* echoes it. Nothing here is scoped, redacted, or revocable.
|
|
36
|
+
*
|
|
37
|
+
* A value that authenticates to a host belongs on the brokered credential
|
|
38
|
+
* path instead, where the process holds a placeholder and the real value is
|
|
39
|
+
* attached per-host on egress — so it is never in the environment, never in
|
|
40
|
+
* a transcript, and never inherited by a child that had no business with it.
|
|
41
|
+
*
|
|
42
|
+
* Inheritance was broken until it was not: a child built through a
|
|
43
|
+
* `configBuilder` never received this at all, because the builder is
|
|
44
|
+
* written by whoever registered the agent and cannot forward a field it was
|
|
45
|
+
* never told about. It is stamped after the builder returns now, for the
|
|
46
|
+
* same reason `parentSpan` and `resumeHandler` are.
|
|
47
|
+
*/
|
|
25
48
|
env?: Record<string, string>
|
|
26
49
|
|
|
27
50
|
/**
|
|
@@ -65,9 +65,42 @@ export interface CreateSubSessionParams {
|
|
|
65
65
|
* is out of scope for this phase (session-hierarchy.md §11 defers the project
|
|
66
66
|
* store to a later phase).
|
|
67
67
|
*/
|
|
68
|
+
/**
|
|
69
|
+
* The part of a Project's configuration a caller may actually set.
|
|
70
|
+
*
|
|
71
|
+
* **Exactly the fields something reads.** `ProjectConfig` declares eight; five
|
|
72
|
+
* enforcement sites read two of them, and the other six have zero readers in
|
|
73
|
+
* production — `maxInterventionDepth` included, whose three apparent hits are
|
|
74
|
+
* all comments claiming a wiring that does not exist. Exposing those here
|
|
75
|
+
* would make a dead field *easier to set*, which is worse than leaving it
|
|
76
|
+
* unreachable: a host would configure a retention policy, get no error, and
|
|
77
|
+
* believe retention was on.
|
|
78
|
+
*
|
|
79
|
+
* The rule is the repo's own: name the code that reads a declaration before
|
|
80
|
+
* shipping it. When a field gains a reader it gains a line here in the same
|
|
81
|
+
* change, and not before.
|
|
82
|
+
*/
|
|
83
|
+
export interface ProjectConfigInput {
|
|
84
|
+
/** Read by the spawn path and both handoff paths. Default 4. */
|
|
85
|
+
maxDelegationDepth?: number
|
|
86
|
+
/** Read by the spawn path and broadcast handoff. Default 8. */
|
|
87
|
+
maxDelegationWidth?: number
|
|
88
|
+
}
|
|
89
|
+
|
|
68
90
|
export interface CreateProjectParams {
|
|
69
91
|
tenantId: TenantId
|
|
70
92
|
name: string
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Per-workspace limits. Omitted fields keep the defaults.
|
|
96
|
+
*
|
|
97
|
+
* Until this existed every project in existence ran at depth 4 / width 8,
|
|
98
|
+
* because the config was hardcoded identically in both stores and there was
|
|
99
|
+
* no way to write one afterwards. A tenant with several workspaces could
|
|
100
|
+
* not give them different limits, which is most of what having several
|
|
101
|
+
* workspaces is for.
|
|
102
|
+
*/
|
|
103
|
+
config?: ProjectConfigInput
|
|
71
104
|
}
|
|
72
105
|
|
|
73
106
|
/**
|
|
@@ -99,13 +132,67 @@ export interface SessionStore {
|
|
|
99
132
|
|
|
100
133
|
getProject(projectId: ProjectId, tenantId: TenantId): Promise<Project | null>
|
|
101
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Change a Project's limits after it exists. OPTIONAL.
|
|
137
|
+
*
|
|
138
|
+
* Optional because widening a store interface is invisible to callers and
|
|
139
|
+
* fatal to implementors: a host with its own `SessionStore` should not stop
|
|
140
|
+
* compiling because the SDK grew a method. Callers check for it; the two
|
|
141
|
+
* stores here implement it.
|
|
142
|
+
*
|
|
143
|
+
* Only the fields in {@link ProjectConfigInput} can move, and an omitted
|
|
144
|
+
* field is left alone rather than reset — a caller raising the width is not
|
|
145
|
+
* saying anything about the depth. Returns the updated Project, or `null`
|
|
146
|
+
* if it does not exist.
|
|
147
|
+
*/
|
|
148
|
+
updateProject?(
|
|
149
|
+
projectId: ProjectId,
|
|
150
|
+
config: ProjectConfigInput,
|
|
151
|
+
tenantId: TenantId,
|
|
152
|
+
): Promise<Project | null>
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Every Project this tenant owns, oldest first. OPTIONAL, same reasoning.
|
|
156
|
+
*
|
|
157
|
+
* The tenant is the isolation boundary, so this is scoped to it and to
|
|
158
|
+
* nothing else — there is no level above Project to filter by.
|
|
159
|
+
*/
|
|
160
|
+
listProjects?(tenantId: TenantId): Promise<readonly Project[]>
|
|
161
|
+
|
|
102
162
|
// Session CRUD ------------------------------------------------------------
|
|
103
163
|
|
|
104
164
|
createSession(params: CreateSessionParams, tenantId: TenantId): Promise<Session>
|
|
105
165
|
|
|
106
166
|
getSession(sessionId: SessionId, tenantId: TenantId): Promise<Session | null>
|
|
107
167
|
|
|
108
|
-
|
|
168
|
+
/**
|
|
169
|
+
* Write a Session back, optionally only if nobody else wrote it first.
|
|
170
|
+
*
|
|
171
|
+
* **`expectedOwnerVersion` is the single-writer lock this level is supposed
|
|
172
|
+
* to own, and it did not exist.** `Session.ownerVersion` is documented as
|
|
173
|
+
* the CAS counter for handoff, but nothing enforced it: both stores
|
|
174
|
+
* overwrote unconditionally, and the handoff's own check compared a
|
|
175
|
+
* snapshot it had read several awaits earlier against itself. Two
|
|
176
|
+
* concurrent handoffs on one idle session both passed, both provisioned a
|
|
177
|
+
* worktree, and one silently erased the other.
|
|
178
|
+
*
|
|
179
|
+
* Supply it and the store compares against the version it HAS STORED —
|
|
180
|
+
* not against the payload, which is the caller's stale copy — and throws
|
|
181
|
+
* {@link StaleSessionError} rather than writing. Omit it and the behaviour
|
|
182
|
+
* is exactly what it always was, which is the compatibility promise: this
|
|
183
|
+
* parameter is optional so that widening the interface stays invisible to
|
|
184
|
+
* callers and harmless to hosts implementing their own store. A required
|
|
185
|
+
* parameter would break every implementor for a guarantee they can opt
|
|
186
|
+
* into.
|
|
187
|
+
*
|
|
188
|
+
* **In-process only, stated rather than implied.** `DiskSessionStore`
|
|
189
|
+
* writes atomically, but its read-compare-write is not a critical section,
|
|
190
|
+
* so two PROCESSES can still both pass the check. Closing that needs a
|
|
191
|
+
* lease with an expiry — not a PID registry, because a Session is durable
|
|
192
|
+
* and written from hosts where a PID is not a checkable fact. The same
|
|
193
|
+
* honesty the spawn lock already carries.
|
|
194
|
+
*/
|
|
195
|
+
updateSession(session: Session, tenantId: TenantId, expectedOwnerVersion?: number): Promise<void>
|
|
109
196
|
|
|
110
197
|
/**
|
|
111
198
|
* List every Session that belongs to the given Thread for the caller's
|