@github/copilot-sdk 1.0.11-preview.2 → 1.0.12-preview.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/index.d.ts CHANGED
@@ -9,7 +9,7 @@ export { BuiltInTools, ToolSet } from "./toolSet.js";
9
9
  export { CopilotSession, type AssistantMessageEvent } from "./session.js";
10
10
  export { defineFactory, FactoryResumeError, isFactoryRunTerminal } from "./factory.js";
11
11
  export { Canvas, CanvasError, createCanvas, type CanvasAction, type CanvasDeclaration, type CanvasHostContext, type CanvasHostContextCapabilities, type CanvasJsonSchema, type CanvasOptions, } from "./canvas.js";
12
- export { defineTool, approveAll, convertMcpCallToolResult, createSessionFsAdapter, CopilotRequestHandler, CopilotWebSocketHandler, CopilotWebSocketCloseStatus, CopilotWebSocketForwarder, SessionFsSqliteTransactionFailure, SYSTEM_MESSAGE_SECTIONS, } from "./types.js";
12
+ export { defineTool, approveAll, createAttributedPermissionResult, convertMcpCallToolResult, createSessionFsAdapter, CopilotRequestHandler, CopilotWebSocketHandler, CopilotWebSocketCloseStatus, CopilotWebSocketForwarder, SessionFsSqliteTransactionFailure, SYSTEM_MESSAGE_SECTIONS, } from "./types.js";
13
13
  export type * from "./generated/session-events.js";
14
- export type { CommandContext, CommandDefinition, CommandHandler, CanvasProviderIdentity, CloudSessionOptions, CloudSessionRepository, AutoModeSwitchHandler, AutoModeSwitchRequest, AutoModeSwitchResponse, AgentStopHandler, AgentStopHookInput, AgentStopHookOutput, UserPromptTransformedHandler, UserPromptTransformedHookInput, UserPromptTransformedHookOutput, CopilotClientMode, CopilotClientOptions, CopilotExpAssignmentResponse, StdioRuntimeConnection, InProcessRuntimeConnection, TcpRuntimeConnection, UriRuntimeConnection, ChildProcessRuntimeConnection, CustomAgentConfig, ElicitationFieldValue, ElicitationHandler, ElicitationParams, ElicitationContext, ElicitationResult, ElicitationSchema, ElicitationSchemaField, ExpConfigEntry, ExpFlagValue, ExitPlanModeHandler, ExitPlanModeRequest, ExitPlanModeResult, ExtensionInfo, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, GitHubMcpToolConfig, GitHubTelemetryNotification, GitHubTelemetryEvent, GitHubTelemetryClientInfo, InfiniteSessionConfig, LargeToolOutputConfig, MemoryConfiguration, UiInputOptions, FactoryLimits, FactoryMeta, MCPStdioServerConfig, MCPHTTPServerConfig, MCPServerConfig, DefaultAgentConfig, BearerTokenProvider, MessageOptions, ManagedSettings, ManagedSettingsPermissions, ModelBilling, ModelBillingTokenPrices, ModelBillingTokenPricesLongContext, CapiSessionOptions, ModelCapabilities, ModelCapabilitiesOverride, ModelInfo, ModelPolicy, NamedProviderConfig, PermissionHandler, PermissionRequest, PermissionRequestedData, PermissionRequestedEvent, PermissionRequestResult, ProviderConfig, ProviderModelConfig, ProviderTokenArgs, RemoteSessionMode, ResumeSessionConfig, SectionOverride, SectionOverrideAction, SectionTransformFn, SessionCapabilities, SessionConfig, SessionConfigBase, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionLifecycleEvent, SessionLifecycleEventMetadata, SessionLifecycleEventType, SessionLifecycleHandler, SessionHooks, SessionCreatedEvent, SessionDeletedEvent, SessionUpdatedEvent, SessionForegroundEvent, SessionBackgroundEvent, SessionContext, SessionListFilter, SessionMetadata, SessionUiApi, SessionFsConfig, SessionFsProvider, SessionFsFileInfo, SessionFsSqliteQueryResult, SessionFsSqliteQueryType, SessionFsSqliteProvider, SessionFsSqliteStatement, SessionFsSqliteTransactionErrorClass, CopilotRequestContext, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageCustomizeConfig, SystemMessageReplaceConfig, SystemMessageSection, TelemetryConfig, TraceContext, TraceContextProvider, Tool, ToolHandler, ToolInvocation, CurrentToolMetadata, ToolTelemetry, ToolResultObject, ToolSearchConfig, TypedSessionEventHandler, TypedSessionLifecycleHandler, ZodSchema, } from "./types.js";
14
+ export type { CommandContext, CommandDefinition, CommandHandler, CanvasProviderIdentity, CloudSessionOptions, CloudSessionRepository, AutoModeSwitchHandler, AutoModeSwitchRequest, AutoModeSwitchResponse, AgentStopHandler, AgentStopHookInput, AgentStopHookOutput, UserPromptTransformedHandler, UserPromptTransformedHookInput, UserPromptTransformedHookOutput, CopilotClientMode, CopilotClientOptions, CopilotExpAssignmentResponse, StdioRuntimeConnection, InProcessRuntimeConnection, TcpRuntimeConnection, UriRuntimeConnection, ChildProcessRuntimeConnection, CustomAgentConfig, ElicitationFieldValue, ElicitationHandler, ElicitationParams, ElicitationContext, ElicitationResult, ElicitationSchema, ElicitationSchemaField, ExpConfigEntry, ExpFlagValue, ExitPlanModeHandler, ExitPlanModeRequest, ExitPlanModeResult, ExtensionInfo, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, GitHubMcpToolConfig, GitHubTelemetryNotification, GitHubTelemetryEvent, GitHubTelemetryClientInfo, InfiniteSessionConfig, LargeToolOutputConfig, MemoryConfiguration, UiInputOptions, FactoryLimits, FactoryMeta, MCPStdioServerConfig, MCPHTTPServerConfig, MCPServerConfig, DefaultAgentConfig, BearerTokenProvider, MessageOptions, ManagedSettings, ManagedSettingsPermissions, ModelBilling, ModelBillingTokenPrices, ModelBillingTokenPricesLongContext, CapiSessionOptions, ModelCapabilities, ModelCapabilitiesOverride, ModelInfo, ModelPolicy, NamedProviderConfig, PermissionHandler, PermissionRequest, PermissionRequestedData, PermissionRequestedEvent, PermissionRequestResult, AttributedPermissionResult, PermissionDecisionContext, PermissionDecisionOutcome, PermissionDecisionSource, PermissionDecisionSurface, ProviderConfig, ProviderModelConfig, ProviderTokenArgs, RemoteSessionMode, ResumeSessionConfig, SectionOverride, SectionOverrideAction, SectionTransformFn, SessionCapabilities, SessionConfig, SessionConfigBase, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionLifecycleEvent, SessionLifecycleEventMetadata, SessionLifecycleEventType, SessionLifecycleHandler, SessionHooks, SessionCreatedEvent, SessionDeletedEvent, SessionUpdatedEvent, SessionForegroundEvent, SessionBackgroundEvent, SessionContext, SessionListFilter, SessionMetadata, SessionUiApi, SessionFsConfig, SessionFsProvider, SessionFsFileInfo, SessionFsSqliteQueryResult, SessionFsSqliteQueryType, SessionFsSqliteProvider, SessionFsSqliteStatement, SessionFsSqliteTransactionErrorClass, CopilotRequestContext, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageCustomizeConfig, SystemMessageReplaceConfig, SystemMessageSection, TelemetryConfig, TraceContext, TraceContextProvider, Tool, ToolHandler, ToolInvocation, CurrentToolMetadata, ToolTelemetry, ToolResultObject, ToolSearchConfig, TypedSessionEventHandler, TypedSessionLifecycleHandler, ZodSchema, } from "./types.js";
15
15
  export type { RunOptions, ResumeOptions, FactoryResumeErrorCode, SessionFactoryApi, FactoryAgentOptions, FactoryContext, FactoryDefinition, FactoryHandle, FactoryJsonSchema, JsonValue, FactoryPipelineStage, FactoryStepOptions, FactoryRunResult, FactoryRunStatus, FactoryRunSummary, FactoryRunDetail, FactoryProgressPage, FactoryProgressLine, FactoryPhaseObservation, FactoryPhaseStatus, FactoryAgentSummary, } from "./factory.js";
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  import {
12
12
  defineTool,
13
13
  approveAll,
14
+ createAttributedPermissionResult,
14
15
  convertMcpCallToolResult,
15
16
  createSessionFsAdapter,
16
17
  CopilotRequestHandler,
@@ -37,6 +38,7 @@ export {
37
38
  ToolSet,
38
39
  approveAll,
39
40
  convertMcpCallToolResult,
41
+ createAttributedPermissionResult,
40
42
  createCanvas,
41
43
  createSessionFsAdapter,
42
44
  defineFactory,
package/dist/session.js CHANGED
@@ -3,6 +3,7 @@ import { ConnectionError, ErrorCodes, ResponseError } from "vscode-jsonrpc/node.
3
3
  import { createSessionRpc } from "./generated/rpc.js";
4
4
  import { CanvasError } from "./canvas.js";
5
5
  import { getTraceContext } from "./telemetry.js";
6
+ import { isAttributedPermissionResult } from "./types.js";
6
7
  import {
7
8
  FACTORY_AGENT_OPTION_KEYS,
8
9
  getFactoryDefinition,
@@ -718,17 +719,22 @@ class CopilotSession {
718
719
  */
719
720
  async _executePermissionAndRespond(requestId, permissionRequest) {
720
721
  try {
721
- const result = await this.permissionHandler(permissionRequest, {
722
+ const handlerResult = await this.permissionHandler(permissionRequest, {
722
723
  sessionId: this.sessionId,
723
724
  managedSettingsEnabled: this.managedSettingsEnabled
724
725
  });
726
+ const isAttributed = isAttributedPermissionResult(handlerResult);
727
+ const result = isAttributed ? handlerResult.result : handlerResult;
728
+ const decisionContext = isAttributed ? handlerResult.decisionContext : void 0;
725
729
  if (result.kind === "no-result") {
726
730
  return;
727
731
  }
728
732
  if (this.disconnected) {
729
733
  return;
730
734
  }
731
- await this.rpc.permissions.handlePendingPermissionRequest({ requestId, result });
735
+ await this.rpc.permissions.handlePendingPermissionRequest(
736
+ decisionContext === void 0 ? { requestId, result } : { requestId, result, decisionContext }
737
+ );
732
738
  } catch (error) {
733
739
  if (this.disconnected) {
734
740
  return;
@@ -1150,7 +1156,13 @@ class CopilotSession {
1150
1156
  }
1151
1157
  try {
1152
1158
  const result = await this.elicitationHandler(context);
1153
- await this.rpc.ui.handlePendingElicitation({ requestId, result });
1159
+ await this.rpc.ui.handlePendingElicitation({
1160
+ requestId,
1161
+ result: {
1162
+ action: result.action,
1163
+ ...result.content ? { content: result.content } : {}
1164
+ }
1165
+ });
1154
1166
  } catch {
1155
1167
  try {
1156
1168
  await this.rpc.ui.handlePendingElicitation({
package/dist/types.d.ts CHANGED
@@ -6,7 +6,7 @@ import type { SessionFsProvider } from "./sessionFsProvider.js";
6
6
  import type { CopilotRequestHandler } from "./copilotRequestHandler.js";
7
7
  import type { PermissionRequest as GeneratedPermissionRequest, PermissionRequestedData as GeneratedPermissionRequestedData, PermissionRequestedEvent as GeneratedPermissionRequestedEvent, ReasoningSummary, SessionLimitsConfig, SessionEvent as GeneratedSessionEvent } from "./generated/session-events.js";
8
8
  import type { CopilotSession } from "./session.js";
9
- import type { JsonValue } from "./factory.js";
9
+ import type { FactoryJsonSchema, JsonValue } from "./factory.js";
10
10
  import type { GitHubTelemetryNotification, ModelBillingTokenPrices, OpenCanvasInstance, RemoteSessionMode, CurrentToolMetadata } from "./generated/rpc.js";
11
11
  import type { ToolSet } from "./toolSet.js";
12
12
  export type { RemoteSessionMode } from "./generated/rpc.js";
@@ -27,6 +27,7 @@ export type { SessionFsSqliteStatement } from "./sessionFsProvider.js";
27
27
  export type { SessionFsSqliteTransactionErrorClass } from "./sessionFsProvider.js";
28
28
  export { SessionFsSqliteTransactionFailure } from "./sessionFsProvider.js";
29
29
  export type { LlmInferenceHeaders } from "./generated/rpc.js";
30
+ export type { PermissionDecisionContext, PermissionDecisionOutcome, PermissionDecisionSource, PermissionDecisionSurface, } from "./generated/rpc.js";
30
31
  export type { CopilotRequestContext } from "./copilotRequestHandler.js";
31
32
  export { CopilotRequestHandler, CopilotWebSocketHandler, CopilotWebSocketCloseStatus, CopilotWebSocketForwarder, } from "./copilotRequestHandler.js";
32
33
  /**
@@ -228,6 +229,12 @@ export interface CopilotClientOptions {
228
229
  * Ignored when connecting to an existing runtime via {@link RuntimeConnection.forUri}.
229
230
  */
230
231
  baseDirectory?: string;
232
+ /**
233
+ * Absolute paths to trusted plugin directories bundled by the host.
234
+ * When non-empty, the complete set is registered with the runtime during
235
+ * startup before any sessions can be created.
236
+ */
237
+ builtinPluginDirectories?: readonly string[];
231
238
  /**
232
239
  * Log level for the Copilot runtime. When omitted, the runtime uses its
233
240
  * own default (currently `"info"`).
@@ -853,7 +860,7 @@ export interface SystemMessageCustomizeConfig {
853
860
  * - Customize mode: Section-level overrides with graceful fallback
854
861
  */
855
862
  export type SystemMessageConfig = SystemMessageAppendConfig | SystemMessageReplaceConfig | SystemMessageCustomizeConfig;
856
- import type { PermissionDecisionRequest } from "./generated/rpc.js";
863
+ import type { PermissionDecisionRequest, PermissionDecisionContext } from "./generated/rpc.js";
857
864
  /**
858
865
  * Permission request types from the server. This is the generated
859
866
  * discriminated union from the runtime schema — switch on `kind` to
@@ -883,10 +890,35 @@ export type PermissionRequestedEvent = Omit<GeneratedPermissionRequestedEvent, "
883
890
  export type PermissionRequestResult = PermissionDecisionRequest["result"] | {
884
891
  kind: "no-result";
885
892
  };
893
+ /**
894
+ * A {@link PermissionRequestResult} annotated with the
895
+ * {@link PermissionDecisionContext} describing how and where the decision was
896
+ * reached. The context is informational only — it never changes permission
897
+ * behavior. Supplying it lets the runtime attribute auto-approval telemetry to
898
+ * the responding surface.
899
+ */
900
+ export interface AttributedPermissionResult {
901
+ kind: "attributed";
902
+ result: PermissionRequestResult;
903
+ decisionContext: PermissionDecisionContext;
904
+ }
905
+ /**
906
+ * Narrows a {@link PermissionHandler} return value to an attributed result.
907
+ */
908
+ export declare function isAttributedPermissionResult(result: PermissionRequestResult | AttributedPermissionResult): result is AttributedPermissionResult;
909
+ /**
910
+ * Pair a permission decision with the context describing how and where it was
911
+ * made, so the runtime can attribute auto-approval telemetry.
912
+ *
913
+ * Passing an already-attributed result replaces the previous context rather
914
+ * than nesting it. The context is informational only and never changes
915
+ * permission behavior.
916
+ */
917
+ export declare function createAttributedPermissionResult(result: PermissionRequestResult | AttributedPermissionResult, decisionContext: PermissionDecisionContext): AttributedPermissionResult;
886
918
  export type PermissionHandler = (request: PermissionRequest, invocation: {
887
919
  sessionId: string;
888
920
  managedSettingsEnabled?: boolean;
889
- }) => Promise<PermissionRequestResult> | PermissionRequestResult;
921
+ }) => Promise<PermissionRequestResult | AttributedPermissionResult> | PermissionRequestResult | AttributedPermissionResult;
890
922
  /**
891
923
  * Approves permission requests when managed settings are disabled.
892
924
  */
@@ -1619,6 +1651,30 @@ export interface FactoryMeta {
1619
1651
  title: string;
1620
1652
  detail?: string;
1621
1653
  }>;
1654
+ /**
1655
+ * Optional declared shape of the arguments this factory expects as `ctx.args`.
1656
+ *
1657
+ * Declaring one is strongly recommended for any factory that reads `ctx.args`.
1658
+ * When the model invokes the factory through the `run_factory` tool, the CLI
1659
+ * validates `args` against this declaration **before** the run starts, so a
1660
+ * malformed call is rejected with a correction hint and retried without ever
1661
+ * creating a run row, prompting the user for permission, or spending credits. A
1662
+ * factory that declares nothing is never validated: a malformed call starts,
1663
+ * takes an approval, spends credits, and then fails inside the factory body.
1664
+ * `factories_manage` with `operation: "inspect"` reports the declared shape so an
1665
+ * agent can read it before invoking.
1666
+ *
1667
+ * This covers the model's `run_factory` path only. `session.factory.run(...)` is
1668
+ * not validated against the declaration, so a factory should still check
1669
+ * `ctx.args` rather than assume the declared shape held.
1670
+ *
1671
+ * Enforcement covers structure — types, required properties, and enum/const
1672
+ * values. Finer constraints such as `minLength`, `pattern`, and
1673
+ * `additionalProperties` are recorded in the declaration but not enforced. See
1674
+ * {@link FactoryJsonSchema} for the accepted subset. A declaration outside that
1675
+ * subset is rejected at registration.
1676
+ */
1677
+ argsSchema?: FactoryJsonSchema;
1622
1678
  /** Optional resource ceilings presented to the user before execution. */
1623
1679
  limits?: FactoryLimits;
1624
1680
  }
package/dist/types.js CHANGED
@@ -112,6 +112,13 @@ const SYSTEM_MESSAGE_SECTIONS = {
112
112
  description: "End-of-prompt instructions: parallel tool calling, persistence, task completion"
113
113
  }
114
114
  };
115
+ function isAttributedPermissionResult(result) {
116
+ return result.kind === "attributed";
117
+ }
118
+ function createAttributedPermissionResult(result, decisionContext) {
119
+ const inner = isAttributedPermissionResult(result) ? result.result : result;
120
+ return { kind: "attributed", result: inner, decisionContext };
121
+ }
115
122
  const approveAll = (request, invocation) => {
116
123
  if (invocation.managedSettingsEnabled) {
117
124
  throw new Error("approveAll cannot be used when managed settings are enabled");
@@ -137,7 +144,9 @@ export {
137
144
  SessionFsSqliteTransactionFailure,
138
145
  approveAll,
139
146
  convertMcpCallToolResult,
147
+ createAttributedPermissionResult,
140
148
  createSessionFsAdapter,
141
149
  defaultJoinSessionPermissionHandler,
142
- defineTool
150
+ defineTool,
151
+ isAttributedPermissionResult
143
152
  };
@@ -53,6 +53,27 @@ const session = await joinSession({
53
53
 
54
54
  The `session` object provides methods for sending messages, logging to the timeline, listening to events, and accessing the RPC API. See the `.d.ts` files in the SDK package for full type information.
55
55
 
56
+ ## Requesting Sensitive Environment Variables
57
+
58
+ The CLI strips sensitive environment variables (for example `GITHUB_TOKEN`) from every extension process before it starts. An extension that needs one asks for it by name:
59
+
60
+ ```js
61
+ import { joinSession } from "@github/copilot-sdk/extension";
62
+
63
+ const session = await joinSession({
64
+ requestedEnvironmentVariables: ["GITHUB_TOKEN"],
65
+ });
66
+
67
+ // Granted values are in process.env once joinSession resolves.
68
+ const token = process.env.GITHUB_TOKEN;
69
+ ```
70
+
71
+ The CLI prompts the user with the extension's name and the exact list of variables requested. If the user approves, only those variables reach this extension and their values are written into `process.env` before `joinSession()` resolves. If the user denies, `joinSession()` rejects, the extension does not load, and its tools never reach the model.
72
+
73
+ An approval is remembered against the exact set of names the user saw, so an extension that later asks for an additional variable prompts again. Names that are unset, or that the CLI does not filter from extensions, are not prompted for.
74
+
75
+ An approved extension can pass a granted value to anything it starts, so ask only for what the extension genuinely needs.
76
+
56
77
  ## Further Reading
57
78
 
58
79
  - `examples.md` — Practical code examples for tools, hooks, events, and complete extensions
package/docs/factories.md CHANGED
@@ -16,11 +16,12 @@ const reviewChanged = defineFactory({
16
16
  "Review changed files and verify the findings. " +
17
17
  "args: { files: string[] } — the paths to review.",
18
18
  phases: [{ title: "Review" }, { title: "Verify" }],
19
- limits: {
20
- maxConcurrentSubagents: 3,
21
- maxTotalSubagents: 10,
22
- timeoutSeconds: 90.5,
23
- maxAiCredits: 5,
19
+ argsSchema: {
20
+ type: "object",
21
+ required: ["files"],
22
+ properties: {
23
+ files: { type: "array", items: { type: "string" } },
24
+ },
24
25
  },
25
26
  },
26
27
  run: async (ctx) => {
@@ -41,9 +42,19 @@ const reviewChanged = defineFactory({
41
42
  const session = await joinSession({ factories: [reviewChanged] });
42
43
  ```
43
44
 
44
- Factory metadata contains a stable `name`, a human-readable `description`, declared `phases`, and optional `limits`. Phase entries contain a `title` and optional `detail`.
45
+ Factory metadata contains a stable `name`, a human-readable `description`, declared `phases`, an optional `argsSchema`, and optional `limits`. Phase entries contain a `title` and optional `detail`.
45
46
 
46
- There is no declared schema for `ctx.args`. The `run_factory` tool forwards `args` verbatim and its parameter is untyped, so **the `description` is the only thing telling an agent what arguments to supply** — state the expected shape there whenever a factory reads `ctx.args`, as the example above does. Arguments supplied by an extension calling `session.factory.run(...)` directly are typed through `defineFactory<TArgs>`, but that typing does not reach the model. A factory that reads `ctx.args` should validate it rather than assume a shape.
47
+ ## Declaring an argument shape
48
+
49
+ A factory that reads `ctx.args` should declare `meta.argsSchema`, as the example above does. When the model invokes the factory through the `run_factory` tool, the CLI validates `args` against the declaration **before** the run starts.
50
+
51
+ Declaring one turns an expensive failure into a cheap one. With a schema, a malformed call is rejected up front — the model gets a correction hint and retries, and no run row, permission prompt, or credit spend happens. Without one, nothing validates: the run starts, takes a user approval, spends credits, and then dies inside the factory body with a confusing error. Agents can read the declared shape with `factories_manage` using `operation: "inspect"`.
52
+
53
+ Enforcement covers structure — types, required properties, and enum or const values. Finer constraints such as `minLength`, `pattern`, or `additionalProperties` are recorded in the declaration but not enforced. The accepted vocabulary is the `FactoryJsonSchema` subset also used for subagent structured output: `type`, `required`, `enum`, `const`, recursive `properties`/`items`, and `anyOf`/`oneOf`/`allOf`. A `type` is one of `null`, `boolean`, `integer`, `number`, `string`, `array`, or `object`, or a non-empty array of those such as `["object", "null"]`. A declaration outside that subset is rejected at registration.
54
+
55
+ `argsSchema` is optional and backward compatible. A factory that omits it behaves exactly as before, so **the `description` is then the only thing telling an agent what arguments to supply** — state the expected shape there.
56
+
57
+ Validation covers the model's `run_factory` path only. An extension calling `session.factory.run(...)` directly is not validated against `argsSchema`; those arguments are typed through `defineFactory<TArgs>` instead, and that typing does not reach the model. So a factory that reads `ctx.args` should still validate it rather than assume a shape — the declared subset does not enforce every constraint, and it does not run at all on the SDK path.
47
58
 
48
59
  `defineFactory<TArgs, TResult>` accepts a `run(context)` function returning `Promise<TResult>`, where `TResult` is `JsonValue | void`. Objects, arrays, strings, numbers, booleans, and `null` are valid results. Returning `undefined` completes the factory with no result. Other non-JSON values are rejected.
49
60
 
@@ -104,7 +115,14 @@ See [factory-patterns.md](./factory-patterns.md) for composable orchestration pa
104
115
 
105
116
  ## Resource limits
106
117
 
107
- Limits may be declared in `meta.limits` and overridden per invocation. All limits must be positive when present.
118
+ Limits may be declared in `meta.limits` and overridden per invocation. Every limit is optional and must be positive when present; an omitted limit leaves that dimension unbounded, except that an omitted `maxConcurrentSubagents` falls back to `maxTotalSubagents`, so a declared total cap also bounds concurrency.
119
+
120
+ Set a ceiling only from real knowledge of what the factory costs, or because the user named one. A guessed ceiling does not make a run safer: it stops a healthy run partway with `factory_limit_reached`, after that run has already spent credits. An agent authoring or invoking a factory on the user's behalf has no basis for estimating a number, so it should leave `limits` unset and bound the work with the factory's own counters instead. Omitting limits does not remove oversight of a model-initiated run: `run_factory` requests permission first, and that prompt shows the effective limits. SDK-initiated `run` and `resume` do not request permission, so an SDK caller that wants a ceiling sets it deliberately, from the cost it already knows.
121
+
122
+ ```js
123
+ // Only when the cost profile is known, or the user asked for this ceiling.
124
+ limits: { maxTotalSubagents: 10 },
125
+ ```
108
126
 
109
127
  - `maxConcurrentSubagents`: Positive integer concurrent-subagent cap. Additional subagents wait in a queue. Queueing applies backpressure and does not fail the run.
110
128
  - `maxTotalSubagents`: Positive integer cumulative admission cap. An attempted subagent beyond the cap ends the attempt with failure kind `maxTotalSubagents`.
@@ -193,7 +211,7 @@ async ({ args, agent, phase }) => {
193
211
  };
194
212
  ```
195
213
 
196
- Authoring registers the factory but does not run it. Invoke it afterwards with `run_factory`. Use `factories_manage` with `operation: "list"` to see the factories already registered in the session and `operation: "inspect"` to read one factory's description, phases, and limits before running it.
214
+ Authoring registers the factory but does not run it. Invoke it afterwards with `run_factory`. Use `factories_manage` with `operation: "list"` to see the factories already registered in the session and `operation: "inspect"` to read one factory's description, phases, declared argument shape, and limits before running it.
197
215
 
198
216
  ## Observe a run
199
217
 
@@ -189,6 +189,6 @@ Compose these freely.
189
189
 
190
190
  Match the orchestration to what was asked. A quick check wants a couple of subagents and single-vote verification; a request to be thorough or comprehensive wants a larger finder pool, a three-to-five vote adversarial pass, and a synthesis stage.
191
191
 
192
- There is no in-script budget object. Scale with your own counters, as in the loop patterns above, and treat the declared limits as the safety ceiling rather than the control mechanism. Only `agent()` spawns are throttled, by `maxConcurrentSubagents` falling back to `maxTotalSubagents`; with neither declared there is no built-in concurrency cap, so declare one before fanning out widely. `parallel` itself is `Promise.all`, so non-agent work in a thunk runs fully concurrently regardless.
192
+ There is no in-script budget object. Scale with your own counters, as in the loop patterns above, and treat any declared limits as the safety ceiling rather than the control mechanism. Only `agent()` spawns are throttled, by `maxConcurrentSubagents` falling back to `maxTotalSubagents`; with neither declared there is no built-in concurrency cap, so bound a wide fan-out with the factory's own counters. Do not invent a ceiling to compensate, and see [Resource limits](./factories.md#resource-limits) for when declaring one is appropriate. `parallel` itself is `Promise.all`, so non-agent work in a thunk runs fully concurrently regardless.
193
193
 
194
194
  These patterns are not exhaustive. Compose novel harnesses — tournament brackets, self-repair loops, staged escalation — when the task calls for it.
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/github/copilot-sdk.git"
6
6
  },
7
- "version": "1.0.11-preview.2",
7
+ "version": "1.0.12-preview.0",
8
8
  "description": "TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC",
9
9
  "main": "./dist/cjs/index.js",
10
10
  "types": "./dist/index.d.ts",
@@ -56,7 +56,7 @@
56
56
  "author": "GitHub",
57
57
  "license": "MIT",
58
58
  "dependencies": {
59
- "@github/copilot": "^1.0.79",
59
+ "@github/copilot": "^1.0.81-5",
60
60
  "koffi": "^3.1.0",
61
61
  "vscode-jsonrpc": "^8.2.1",
62
62
  "zod": "^4.3.6"