operon-agents 0.1.0-alpha.30 → 0.1.0-alpha.32

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/README.md CHANGED
@@ -3,7 +3,8 @@
3
3
  Public SDK entrypoint for building agents.
4
4
 
5
5
  ```ts
6
- import { Agent, Runner, Session, ChatModel, tool } from "operon-agents";
6
+ import { Agent, ChatModel, defineTool } from "operon-agents";
7
+ import { Runner, Session } from "operon-agents/advanced";
7
8
  ```
8
9
 
9
10
  Use `operon-agents` from applications. `operon-agents-core` is the lower-level
@@ -43,7 +44,7 @@ const provider = new NodeTracerProvider({
43
44
  const tracing = new OTelTracingProcessor({ tracer: provider.getTracer("my-agent"), tracerProvider: provider, content: "delta", shutdownProvider: true });
44
45
 
45
46
  const harness = await createLocalHarness({
46
- model,
47
+ config: { defaults: { model } },
47
48
  infrastructure: () => ({ tracing }),
48
49
  });
49
50
  ```
@@ -0,0 +1,15 @@
1
+ /**
2
+ * `operon-agents/advanced` — everything beyond the main entry point: extension and cron plumbing,
3
+ * custom capabilities, stores, providers, MCP wiring and the event and store contracts.
4
+ *
5
+ * Supported, but for hosts composing their own deployment. Most applications only need
6
+ * `operon-agents`. Engine internals with no stability guarantee live on `operon-agents/internal`.
7
+ */
8
+ export * from "./harness.ts";
9
+ export * from "./extensions/index.ts";
10
+ export * from "./cron/index.ts";
11
+ export * from "./providers.ts";
12
+ export * from "./local.ts";
13
+ export * from "./workspace-mcp.ts";
14
+ export * from "operon-agents-core";
15
+ //# sourceMappingURL=advanced.d.ts.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * `operon-agents/advanced` — everything beyond the main entry point: extension and cron plumbing,
3
+ * custom capabilities, stores, providers, MCP wiring and the event and store contracts.
4
+ *
5
+ * Supported, but for hosts composing their own deployment. Most applications only need
6
+ * `operon-agents`. Engine internals with no stability guarantee live on `operon-agents/internal`.
7
+ */
8
+ export * from "./harness.js";
9
+ export * from "./extensions/index.js";
10
+ export * from "./cron/index.js";
11
+ export * from "./providers.js";
12
+ export * from "./local.js";
13
+ export * from "./workspace-mcp.js";
14
+ export * from "operon-agents-core";
15
+ //# sourceMappingURL=advanced.js.map
@@ -7,7 +7,7 @@
7
7
  * in-process for tests.
8
8
  */
9
9
  import { type ChildProcess } from "node:child_process";
10
- import type { AgentEvent, ApprovalRequest, ApprovalResponse, QuestionRequest, QuestionResult, RunResult, SessionSummary } from "operon-agents-core";
10
+ import type { AgentEvent, ApprovalRequest, ApprovalResponse, QuestionRequest, QuestionResult, RunResult, SessionConfig, SessionSummary } from "operon-agents-core";
11
11
  import { type JsonRpcTransport } from "./codec.ts";
12
12
  import { type ClientCapabilities, type InitializeResult, type SessionFollowUpResult, type SessionInfo, type SessionSnapshotResult, type SessionSteerResult } from "./protocol.ts";
13
13
  export type ApprovalHandler = (request: ApprovalRequest, sessionId: string) => Promise<ApprovalResponse> | ApprovalResponse;
@@ -49,10 +49,12 @@ export declare class AppServerClient {
49
49
  workDir?: string;
50
50
  title?: string;
51
51
  model?: string;
52
+ config?: SessionConfig;
52
53
  }): Promise<SessionInfo>;
53
54
  resumeSession(sessionId: string): Promise<SessionInfo>;
54
55
  forkSession(sessionId: string, opts?: {
55
56
  title?: string;
57
+ config?: SessionConfig;
56
58
  }): Promise<SessionInfo>;
57
59
  listSessions(): Promise<readonly SessionSummary[]>;
58
60
  closeSession(sessionId: string): Promise<unknown>;
@@ -5,14 +5,22 @@
5
5
  *
6
6
  * operon-app-server --home ~/.agent --workdir /repo --model anthropic/claude-opus-4-...
7
7
  *
8
+ * Configuration comes from the same `config.toml` files any other host reads (`loadHarnessConfig`:
9
+ * `<home>/config.toml`, then the working directory's `.agents/config.toml` and
10
+ * `.agents/config.local.toml`), with the command-line flags laid over it. `--no-config` skips the
11
+ * files.
12
+ *
8
13
  * stdout carries the protocol (NDJSON JSON-RPC). stderr is logs. We defensively
9
14
  * redirect console.log/info/debug to stderr so a stray log can never corrupt the
10
15
  * protocol stream.
11
16
  */
12
- import { DiskSessionRepository } from "operon-agents-core";
17
+ import { DiskSessionRepository, loadHarnessConfig } from "operon-agents-core";
13
18
  import { createHarness } from "../harness.js";
14
19
  import { nodeStreamTransport } from "./codec.js";
15
20
  import { AppServer } from "./server.js";
21
+ const PERMISSION_MODES = ["manual", "workspace", "yolo", "auto"];
22
+ /** What this binary has always run on when nothing names a model. */
23
+ const FALLBACK_MODEL = "anthropic/claude-opus-4-8";
16
24
  function parseArgs(argv) {
17
25
  const out = {};
18
26
  for (let i = 0; i < argv.length; i++) {
@@ -31,10 +39,13 @@ function parseArgs(argv) {
31
39
  break;
32
40
  case "--permission": {
33
41
  const mode = take();
34
- if (mode === "manual" || mode === "workspace" || mode === "yolo")
42
+ if (PERMISSION_MODES.includes(mode))
35
43
  out.permission = mode;
36
44
  break;
37
45
  }
46
+ case "--no-config":
47
+ out.noConfig = true;
48
+ break;
38
49
  default:
39
50
  break;
40
51
  }
@@ -52,11 +63,25 @@ function redirectStdoutLogsToStderr() {
52
63
  async function main() {
53
64
  redirectStdoutLogsToStderr();
54
65
  const args = parseArgs(process.argv.slice(2));
66
+ // The files first, the flags over them: one configuration, whichever way it was written.
67
+ const file = args.noConfig === true
68
+ ? { defaults: {} }
69
+ : await loadHarnessConfig({
70
+ ...(args.home !== undefined ? { homeDir: args.home } : {}),
71
+ ...(args.workdir !== undefined ? { cwd: args.workdir } : {}),
72
+ });
73
+ const config = {
74
+ ...file,
75
+ defaults: {
76
+ ...file.defaults,
77
+ model: args.model ?? file.defaults.model ?? FALLBACK_MODEL,
78
+ ...(args.permission !== undefined ? { permission: { ...file.defaults.permission, mode: args.permission } } : {}),
79
+ },
80
+ ...(args.workdir !== undefined ? { workDir: args.workdir } : {}),
81
+ };
55
82
  const harness = createHarness({
56
- model: args.model ?? "anthropic/claude-opus-4-8",
83
+ config,
57
84
  ...(args.home !== undefined ? { infrastructure: () => ({ sessionRepository: new DiskSessionRepository(args.home) }) } : {}),
58
- ...(args.workdir !== undefined ? { workDir: args.workdir } : {}),
59
- permission: { mode: args.permission ?? "yolo" },
60
85
  });
61
86
  const transport = nodeStreamTransport(process.stdin, process.stdout, {
62
87
  onParseError: (line, error) => process.stderr.write(`parse error: ${String(error)} on: ${line.slice(0, 200)}\n`),
@@ -5,7 +5,7 @@
5
5
  * handler touches it. A miss is an `InvalidParams` error that names the field.
6
6
  */
7
7
  import { z } from "zod";
8
- import type { Message, QuestionItem } from "operon-agents-core";
8
+ import { type Message, type QuestionItem, type SessionConfig } from "operon-agents-core";
9
9
  import type { ClientCancelRequestParams, ClientRequestApprovalParams, ClientRequestQuestionParams, InitializeParams, SessionFollowUpParams, SessionForkParams, SessionInvokeParams, SessionNewParams, SessionPromptParams, SessionRef, SessionRespondParams, SessionResumeParams, SessionSnapshotParams, SessionSteerParams } from "./protocol.ts";
10
10
  export declare const SessionRefSchema: z.ZodObject<{
11
11
  sessionId: z.ZodString;
@@ -25,12 +25,426 @@ export declare const SessionNewParamsSchema: z.ZodObject<{
25
25
  workDir: z.ZodOptional<z.ZodString>;
26
26
  title: z.ZodOptional<z.ZodString>;
27
27
  model: z.ZodOptional<z.ZodString>;
28
+ config: z.ZodOptional<z.ZodPipe<z.ZodObject<{
29
+ model: z.ZodOptional<z.ZodString>;
30
+ modelSettings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
31
+ thinking: z.ZodOptional<z.ZodString>;
32
+ agent: z.ZodOptional<z.ZodString>;
33
+ tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
34
+ appendSystemPrompt: z.ZodOptional<z.ZodString>;
35
+ mcp: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
36
+ servers: z.ZodRecord<z.ZodString, z.ZodPreprocess<z.ZodPipe<z.ZodObject<{
37
+ type: z.ZodOptional<z.ZodEnum<{
38
+ stdio: "stdio";
39
+ http: "http";
40
+ }>>;
41
+ transport: z.ZodOptional<z.ZodEnum<{
42
+ stdio: "stdio";
43
+ http: "http";
44
+ }>>;
45
+ command: z.ZodOptional<z.ZodString>;
46
+ args: z.ZodOptional<z.ZodArray<z.ZodString>>;
47
+ cwd: z.ZodOptional<z.ZodString>;
48
+ url: z.ZodOptional<z.ZodString>;
49
+ env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
50
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
51
+ allowedTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
52
+ blockedTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
53
+ enabled: z.ZodOptional<z.ZodBoolean>;
54
+ startupTimeoutMs: z.ZodOptional<z.ZodNumber>;
55
+ toolTimeoutMs: z.ZodOptional<z.ZodNumber>;
56
+ bearerTokenEnvVar: z.ZodOptional<z.ZodString>;
57
+ keepAliveIntervalMs: z.ZodOptional<z.ZodNumber>;
58
+ keepAliveTimeoutMs: z.ZodOptional<z.ZodNumber>;
59
+ oauth: z.ZodOptional<z.ZodObject<{
60
+ clientId: z.ZodString;
61
+ clientSecret: z.ZodOptional<z.ZodString>;
62
+ callbackPort: z.ZodOptional<z.ZodNumber>;
63
+ callbackUrl: z.ZodOptional<z.ZodString>;
64
+ }, z.core.$strip>>;
65
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
66
+ }, z.core.$strip>, z.ZodTransform<{
67
+ transport: "stdio" | "http";
68
+ command?: string | undefined;
69
+ args?: string[] | undefined;
70
+ cwd?: string | undefined;
71
+ url?: string | undefined;
72
+ env?: Record<string, string> | undefined;
73
+ headers?: Record<string, string> | undefined;
74
+ allowedTools?: string[] | undefined;
75
+ blockedTools?: string[] | undefined;
76
+ enabled?: boolean | undefined;
77
+ startupTimeoutMs?: number | undefined;
78
+ toolTimeoutMs?: number | undefined;
79
+ bearerTokenEnvVar?: string | undefined;
80
+ keepAliveIntervalMs?: number | undefined;
81
+ keepAliveTimeoutMs?: number | undefined;
82
+ oauth?: {
83
+ clientId: string;
84
+ clientSecret?: string | undefined;
85
+ callbackPort?: number | undefined;
86
+ callbackUrl?: string | undefined;
87
+ } | undefined;
88
+ scopes?: string[] | undefined;
89
+ }, {
90
+ type?: "stdio" | "http" | undefined;
91
+ transport?: "stdio" | "http" | undefined;
92
+ command?: string | undefined;
93
+ args?: string[] | undefined;
94
+ cwd?: string | undefined;
95
+ url?: string | undefined;
96
+ env?: Record<string, string> | undefined;
97
+ headers?: Record<string, string> | undefined;
98
+ allowedTools?: string[] | undefined;
99
+ blockedTools?: string[] | undefined;
100
+ enabled?: boolean | undefined;
101
+ startupTimeoutMs?: number | undefined;
102
+ toolTimeoutMs?: number | undefined;
103
+ bearerTokenEnvVar?: string | undefined;
104
+ keepAliveIntervalMs?: number | undefined;
105
+ keepAliveTimeoutMs?: number | undefined;
106
+ oauth?: {
107
+ clientId: string;
108
+ clientSecret?: string | undefined;
109
+ callbackPort?: number | undefined;
110
+ callbackUrl?: string | undefined;
111
+ } | undefined;
112
+ scopes?: string[] | undefined;
113
+ }>>>>;
114
+ }, z.core.$strict>]>>;
115
+ skills: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
116
+ roots: z.ZodOptional<z.ZodArray<z.ZodString>>;
117
+ includeDefaultRoots: z.ZodOptional<z.ZodBoolean>;
118
+ }, z.core.$strict>]>>;
119
+ hooks: z.ZodOptional<z.ZodArray<z.ZodObject<{
120
+ event: z.ZodString;
121
+ matcher: z.ZodOptional<z.ZodString>;
122
+ command: z.ZodString;
123
+ timeout: z.ZodOptional<z.ZodNumber>;
124
+ }, z.core.$strip>>>;
125
+ permission: z.ZodOptional<z.ZodObject<{
126
+ mode: z.ZodOptional<z.ZodEnum<{
127
+ auto: "auto";
128
+ manual: "manual";
129
+ workspace: "workspace";
130
+ yolo: "yolo";
131
+ }>>;
132
+ autoApproval: z.ZodOptional<z.ZodObject<{
133
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
134
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
135
+ environment: z.ZodOptional<z.ZodArray<z.ZodString>>;
136
+ twoStageMode: z.ZodOptional<z.ZodEnum<{
137
+ thinking: "thinking";
138
+ both: "both";
139
+ fast: "fast";
140
+ }>>;
141
+ }, z.core.$strict>>;
142
+ rules: z.ZodOptional<z.ZodArray<z.ZodObject<{
143
+ decision: z.ZodEnum<{
144
+ allow: "allow";
145
+ deny: "deny";
146
+ ask: "ask";
147
+ }>;
148
+ scope: z.ZodEnum<{
149
+ user: "user";
150
+ "turn-override": "turn-override";
151
+ "session-runtime": "session-runtime";
152
+ project: "project";
153
+ }>;
154
+ pattern: z.ZodString;
155
+ reason: z.ZodOptional<z.ZodString>;
156
+ }, z.core.$strip>>>;
157
+ }, z.core.$strict>>;
158
+ extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
159
+ subagents: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
160
+ workflowTool: z.ZodOptional<z.ZodBoolean>;
161
+ maxConcurrent: z.ZodOptional<z.ZodNumber>;
162
+ }, z.core.$strict>]>>;
163
+ limits: z.ZodOptional<z.ZodObject<{
164
+ maxTurns: z.ZodOptional<z.ZodNumber>;
165
+ maxStepsPerTurn: z.ZodOptional<z.ZodNumber>;
166
+ }, z.core.$strict>>;
167
+ }, z.core.$strict>, z.ZodTransform<SessionConfig, {
168
+ model?: string | undefined;
169
+ modelSettings?: Record<string, unknown> | undefined;
170
+ thinking?: string | undefined;
171
+ agent?: string | undefined;
172
+ tools?: string[] | undefined;
173
+ appendSystemPrompt?: string | undefined;
174
+ mcp?: false | {
175
+ servers: Record<string, {
176
+ transport: "stdio" | "http";
177
+ command?: string | undefined;
178
+ args?: string[] | undefined;
179
+ cwd?: string | undefined;
180
+ url?: string | undefined;
181
+ env?: Record<string, string> | undefined;
182
+ headers?: Record<string, string> | undefined;
183
+ allowedTools?: string[] | undefined;
184
+ blockedTools?: string[] | undefined;
185
+ enabled?: boolean | undefined;
186
+ startupTimeoutMs?: number | undefined;
187
+ toolTimeoutMs?: number | undefined;
188
+ bearerTokenEnvVar?: string | undefined;
189
+ keepAliveIntervalMs?: number | undefined;
190
+ keepAliveTimeoutMs?: number | undefined;
191
+ oauth?: {
192
+ clientId: string;
193
+ clientSecret?: string | undefined;
194
+ callbackPort?: number | undefined;
195
+ callbackUrl?: string | undefined;
196
+ } | undefined;
197
+ scopes?: string[] | undefined;
198
+ }>;
199
+ } | undefined;
200
+ skills?: false | {
201
+ roots?: string[] | undefined;
202
+ includeDefaultRoots?: boolean | undefined;
203
+ } | undefined;
204
+ hooks?: {
205
+ event: string;
206
+ command: string;
207
+ matcher?: string | undefined;
208
+ timeout?: number | undefined;
209
+ }[] | undefined;
210
+ permission?: {
211
+ mode?: "manual" | "auto" | "workspace" | "yolo" | undefined;
212
+ autoApproval?: {
213
+ allow?: string[] | undefined;
214
+ deny?: string[] | undefined;
215
+ environment?: string[] | undefined;
216
+ twoStageMode?: "thinking" | "both" | "fast" | undefined;
217
+ } | undefined;
218
+ rules?: {
219
+ decision: "allow" | "deny" | "ask";
220
+ scope: "user" | "turn-override" | "session-runtime" | "project";
221
+ pattern: string;
222
+ reason?: string | undefined;
223
+ }[] | undefined;
224
+ } | undefined;
225
+ extensions?: Record<string, unknown> | undefined;
226
+ subagents?: false | {
227
+ workflowTool?: boolean | undefined;
228
+ maxConcurrent?: number | undefined;
229
+ } | undefined;
230
+ limits?: {
231
+ maxTurns?: number | undefined;
232
+ maxStepsPerTurn?: number | undefined;
233
+ } | undefined;
234
+ }>>>;
28
235
  }, z.core.$strip>;
29
236
  export declare const SessionResumeParamsSchema: z.ZodObject<{
30
237
  sessionId: z.ZodString;
31
238
  }, z.core.$strip>;
32
239
  export declare const SessionForkParamsSchema: z.ZodObject<{
33
240
  title: z.ZodOptional<z.ZodString>;
241
+ config: z.ZodOptional<z.ZodPipe<z.ZodObject<{
242
+ model: z.ZodOptional<z.ZodString>;
243
+ modelSettings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
244
+ thinking: z.ZodOptional<z.ZodString>;
245
+ agent: z.ZodOptional<z.ZodString>;
246
+ tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
247
+ appendSystemPrompt: z.ZodOptional<z.ZodString>;
248
+ mcp: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
249
+ servers: z.ZodRecord<z.ZodString, z.ZodPreprocess<z.ZodPipe<z.ZodObject<{
250
+ type: z.ZodOptional<z.ZodEnum<{
251
+ stdio: "stdio";
252
+ http: "http";
253
+ }>>;
254
+ transport: z.ZodOptional<z.ZodEnum<{
255
+ stdio: "stdio";
256
+ http: "http";
257
+ }>>;
258
+ command: z.ZodOptional<z.ZodString>;
259
+ args: z.ZodOptional<z.ZodArray<z.ZodString>>;
260
+ cwd: z.ZodOptional<z.ZodString>;
261
+ url: z.ZodOptional<z.ZodString>;
262
+ env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
263
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
264
+ allowedTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
265
+ blockedTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
266
+ enabled: z.ZodOptional<z.ZodBoolean>;
267
+ startupTimeoutMs: z.ZodOptional<z.ZodNumber>;
268
+ toolTimeoutMs: z.ZodOptional<z.ZodNumber>;
269
+ bearerTokenEnvVar: z.ZodOptional<z.ZodString>;
270
+ keepAliveIntervalMs: z.ZodOptional<z.ZodNumber>;
271
+ keepAliveTimeoutMs: z.ZodOptional<z.ZodNumber>;
272
+ oauth: z.ZodOptional<z.ZodObject<{
273
+ clientId: z.ZodString;
274
+ clientSecret: z.ZodOptional<z.ZodString>;
275
+ callbackPort: z.ZodOptional<z.ZodNumber>;
276
+ callbackUrl: z.ZodOptional<z.ZodString>;
277
+ }, z.core.$strip>>;
278
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
279
+ }, z.core.$strip>, z.ZodTransform<{
280
+ transport: "stdio" | "http";
281
+ command?: string | undefined;
282
+ args?: string[] | undefined;
283
+ cwd?: string | undefined;
284
+ url?: string | undefined;
285
+ env?: Record<string, string> | undefined;
286
+ headers?: Record<string, string> | undefined;
287
+ allowedTools?: string[] | undefined;
288
+ blockedTools?: string[] | undefined;
289
+ enabled?: boolean | undefined;
290
+ startupTimeoutMs?: number | undefined;
291
+ toolTimeoutMs?: number | undefined;
292
+ bearerTokenEnvVar?: string | undefined;
293
+ keepAliveIntervalMs?: number | undefined;
294
+ keepAliveTimeoutMs?: number | undefined;
295
+ oauth?: {
296
+ clientId: string;
297
+ clientSecret?: string | undefined;
298
+ callbackPort?: number | undefined;
299
+ callbackUrl?: string | undefined;
300
+ } | undefined;
301
+ scopes?: string[] | undefined;
302
+ }, {
303
+ type?: "stdio" | "http" | undefined;
304
+ transport?: "stdio" | "http" | undefined;
305
+ command?: string | undefined;
306
+ args?: string[] | undefined;
307
+ cwd?: string | undefined;
308
+ url?: string | undefined;
309
+ env?: Record<string, string> | undefined;
310
+ headers?: Record<string, string> | undefined;
311
+ allowedTools?: string[] | undefined;
312
+ blockedTools?: string[] | undefined;
313
+ enabled?: boolean | undefined;
314
+ startupTimeoutMs?: number | undefined;
315
+ toolTimeoutMs?: number | undefined;
316
+ bearerTokenEnvVar?: string | undefined;
317
+ keepAliveIntervalMs?: number | undefined;
318
+ keepAliveTimeoutMs?: number | undefined;
319
+ oauth?: {
320
+ clientId: string;
321
+ clientSecret?: string | undefined;
322
+ callbackPort?: number | undefined;
323
+ callbackUrl?: string | undefined;
324
+ } | undefined;
325
+ scopes?: string[] | undefined;
326
+ }>>>>;
327
+ }, z.core.$strict>]>>;
328
+ skills: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
329
+ roots: z.ZodOptional<z.ZodArray<z.ZodString>>;
330
+ includeDefaultRoots: z.ZodOptional<z.ZodBoolean>;
331
+ }, z.core.$strict>]>>;
332
+ hooks: z.ZodOptional<z.ZodArray<z.ZodObject<{
333
+ event: z.ZodString;
334
+ matcher: z.ZodOptional<z.ZodString>;
335
+ command: z.ZodString;
336
+ timeout: z.ZodOptional<z.ZodNumber>;
337
+ }, z.core.$strip>>>;
338
+ permission: z.ZodOptional<z.ZodObject<{
339
+ mode: z.ZodOptional<z.ZodEnum<{
340
+ auto: "auto";
341
+ manual: "manual";
342
+ workspace: "workspace";
343
+ yolo: "yolo";
344
+ }>>;
345
+ autoApproval: z.ZodOptional<z.ZodObject<{
346
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
347
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
348
+ environment: z.ZodOptional<z.ZodArray<z.ZodString>>;
349
+ twoStageMode: z.ZodOptional<z.ZodEnum<{
350
+ thinking: "thinking";
351
+ both: "both";
352
+ fast: "fast";
353
+ }>>;
354
+ }, z.core.$strict>>;
355
+ rules: z.ZodOptional<z.ZodArray<z.ZodObject<{
356
+ decision: z.ZodEnum<{
357
+ allow: "allow";
358
+ deny: "deny";
359
+ ask: "ask";
360
+ }>;
361
+ scope: z.ZodEnum<{
362
+ user: "user";
363
+ "turn-override": "turn-override";
364
+ "session-runtime": "session-runtime";
365
+ project: "project";
366
+ }>;
367
+ pattern: z.ZodString;
368
+ reason: z.ZodOptional<z.ZodString>;
369
+ }, z.core.$strip>>>;
370
+ }, z.core.$strict>>;
371
+ extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
372
+ subagents: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
373
+ workflowTool: z.ZodOptional<z.ZodBoolean>;
374
+ maxConcurrent: z.ZodOptional<z.ZodNumber>;
375
+ }, z.core.$strict>]>>;
376
+ limits: z.ZodOptional<z.ZodObject<{
377
+ maxTurns: z.ZodOptional<z.ZodNumber>;
378
+ maxStepsPerTurn: z.ZodOptional<z.ZodNumber>;
379
+ }, z.core.$strict>>;
380
+ }, z.core.$strict>, z.ZodTransform<SessionConfig, {
381
+ model?: string | undefined;
382
+ modelSettings?: Record<string, unknown> | undefined;
383
+ thinking?: string | undefined;
384
+ agent?: string | undefined;
385
+ tools?: string[] | undefined;
386
+ appendSystemPrompt?: string | undefined;
387
+ mcp?: false | {
388
+ servers: Record<string, {
389
+ transport: "stdio" | "http";
390
+ command?: string | undefined;
391
+ args?: string[] | undefined;
392
+ cwd?: string | undefined;
393
+ url?: string | undefined;
394
+ env?: Record<string, string> | undefined;
395
+ headers?: Record<string, string> | undefined;
396
+ allowedTools?: string[] | undefined;
397
+ blockedTools?: string[] | undefined;
398
+ enabled?: boolean | undefined;
399
+ startupTimeoutMs?: number | undefined;
400
+ toolTimeoutMs?: number | undefined;
401
+ bearerTokenEnvVar?: string | undefined;
402
+ keepAliveIntervalMs?: number | undefined;
403
+ keepAliveTimeoutMs?: number | undefined;
404
+ oauth?: {
405
+ clientId: string;
406
+ clientSecret?: string | undefined;
407
+ callbackPort?: number | undefined;
408
+ callbackUrl?: string | undefined;
409
+ } | undefined;
410
+ scopes?: string[] | undefined;
411
+ }>;
412
+ } | undefined;
413
+ skills?: false | {
414
+ roots?: string[] | undefined;
415
+ includeDefaultRoots?: boolean | undefined;
416
+ } | undefined;
417
+ hooks?: {
418
+ event: string;
419
+ command: string;
420
+ matcher?: string | undefined;
421
+ timeout?: number | undefined;
422
+ }[] | undefined;
423
+ permission?: {
424
+ mode?: "manual" | "auto" | "workspace" | "yolo" | undefined;
425
+ autoApproval?: {
426
+ allow?: string[] | undefined;
427
+ deny?: string[] | undefined;
428
+ environment?: string[] | undefined;
429
+ twoStageMode?: "thinking" | "both" | "fast" | undefined;
430
+ } | undefined;
431
+ rules?: {
432
+ decision: "allow" | "deny" | "ask";
433
+ scope: "user" | "turn-override" | "session-runtime" | "project";
434
+ pattern: string;
435
+ reason?: string | undefined;
436
+ }[] | undefined;
437
+ } | undefined;
438
+ extensions?: Record<string, unknown> | undefined;
439
+ subagents?: false | {
440
+ workflowTool?: boolean | undefined;
441
+ maxConcurrent?: number | undefined;
442
+ } | undefined;
443
+ limits?: {
444
+ maxTurns?: number | undefined;
445
+ maxStepsPerTurn?: number | undefined;
446
+ } | undefined;
447
+ }>>>;
34
448
  sessionId: z.ZodString;
35
449
  }, z.core.$strip>;
36
450
  export declare const SessionCloseParamsSchema: z.ZodObject<{
@@ -5,6 +5,7 @@
5
5
  * handler touches it. A miss is an `InvalidParams` error that names the field.
6
6
  */
7
7
  import { z } from "zod";
8
+ import { SessionConfigSchema } from "operon-agents-core";
8
9
  import { ErrorCode, INVOKABLE_METHODS } from "./protocol.js";
9
10
  import { RpcError } from "./codec.js";
10
11
  const sessionRef = { sessionId: z.string().min(1, "sessionId required") };
@@ -14,13 +15,16 @@ export const InitializeParamsSchema = z.object({
14
15
  clientInfo: z.object({ name: z.string(), version: z.string().optional() }).optional(),
15
16
  clientCapabilities: z.object({ approval: z.boolean().optional(), question: z.boolean().optional() }).optional(),
16
17
  });
18
+ /** The one session-configuration schema, as every other entry point validates it. */
19
+ const sessionConfig = SessionConfigSchema.transform((value) => value).optional();
17
20
  export const SessionNewParamsSchema = z.object({
18
21
  workDir: z.string().optional(),
19
22
  title: z.string().optional(),
20
23
  model: z.string().optional(),
24
+ config: sessionConfig,
21
25
  });
22
26
  export const SessionResumeParamsSchema = SessionRefSchema;
23
- export const SessionForkParamsSchema = z.object({ ...sessionRef, title: z.string().optional() });
27
+ export const SessionForkParamsSchema = z.object({ ...sessionRef, title: z.string().optional(), config: sessionConfig });
24
28
  export const SessionCloseParamsSchema = SessionRefSchema;
25
29
  export const SessionCancelParamsSchema = SessionRefSchema;
26
30
  const isMessageLike = (value) => typeof value === "object" && value !== null && typeof value.role === "string";
@@ -16,7 +16,7 @@
16
16
  * server → host request reverse-RPC: `client/requestApproval` / `…Question`
17
17
  * host → server response the host's answer to a reverse-RPC request
18
18
  */
19
- import type { AgentEvent, AgentInput, ApprovalRequest, ApprovalResponse, PermissionMode, QuestionRequest, QuestionResult, RunResult, SessionSnapshot, SessionSummary } from "operon-agents-core";
19
+ import type { AgentEvent, AgentInput, ApprovalRequest, ApprovalResponse, PermissionMode, QuestionRequest, QuestionResult, RunResult, SessionConfig, SessionSnapshot, SessionSummary } from "operon-agents-core";
20
20
  /** Bump on any breaking wire change. Integer, not semver. */
21
21
  export declare const PROTOCOL_VERSION = 1;
22
22
  export type JsonRpcId = string | number;
@@ -114,8 +114,16 @@ export interface InitializeResult {
114
114
  export interface SessionNewParams {
115
115
  readonly workDir?: string;
116
116
  readonly title?: string;
117
- /** Per-session model id (`provider/model`), applied via setModel after creation. */
117
+ /** Per-session model id (`provider/model`). Shorthand for `config.model`, which it overrides. */
118
118
  readonly model?: string;
119
+ /**
120
+ * The session's setup, as data: model, tool and agent NAMES registered on the server's harness,
121
+ * MCP servers, permission, extension parameters, limits. A field given replaces the server's
122
+ * default; a field left out inherits it. Stored with the session, so `session/resume` needs none
123
+ * of it repeated. It is checked against the server's policy like any other configuration — the
124
+ * wire is not a way around it.
125
+ */
126
+ readonly config?: SessionConfig;
119
127
  }
120
128
  export interface SessionRef {
121
129
  readonly sessionId: string;
@@ -128,6 +136,8 @@ export interface SessionResumeParams extends SessionRef {
128
136
  }
129
137
  export interface SessionForkParams extends SessionRef {
130
138
  readonly title?: string;
139
+ /** Adjustments to the source session's setup, field by field. See `SessionNewParams.config`. */
140
+ readonly config?: SessionConfig;
131
141
  }
132
142
  export interface SessionCloseParams extends SessionRef {
133
143
  }
@@ -178,9 +188,8 @@ export interface SessionFollowUpParams extends SessionRef {
178
188
  readonly text: string;
179
189
  }
180
190
  export interface SessionFollowUpResult {
181
- /** False when the session has no active run; callers should use `session/prompt` instead. */
182
191
  readonly accepted: boolean;
183
- /** Correlation id (see `SessionSteerResult.steerId`); absent when not accepted. */
192
+ /** Correlation id (see `SessionSteerResult.steerId`). */
184
193
  readonly steerId?: string;
185
194
  }
186
195
  export interface SessionCancelParams extends SessionRef {