@github/copilot-sdk 0.2.2 → 0.3.0-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/cjs/client.js +39 -4
- package/dist/cjs/extension.js +2 -4
- package/dist/cjs/generated/rpc.js +24 -5
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/session.js +2 -1
- package/dist/cjs/sessionFsProvider.js +121 -0
- package/dist/cjs/types.js +51 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +39 -4
- package/dist/extension.d.ts +1 -1
- package/dist/extension.js +3 -3
- package/dist/generated/rpc.d.ts +1214 -1027
- package/dist/generated/rpc.js +24 -5
- package/dist/generated/session-events.d.ts +3490 -2894
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9 -1
- package/dist/session.js +2 -1
- package/dist/sessionFsProvider.d.ts +44 -0
- package/dist/sessionFsProvider.js +97 -0
- package/dist/types.d.ts +96 -13
- package/dist/types.js +48 -0
- package/docs/agent-author.md +22 -14
- package/docs/examples.md +35 -31
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { CopilotClient } from "./client.js";
|
|
7
7
|
export { CopilotSession, type AssistantMessageEvent } from "./session.js";
|
|
8
|
-
export { defineTool, approveAll, SYSTEM_PROMPT_SECTIONS } from "./types.js";
|
|
9
|
-
export type { CommandContext, CommandDefinition, CommandHandler, ConnectionState, CopilotClientOptions, CustomAgentConfig, ElicitationFieldValue, ElicitationHandler, ElicitationParams, ElicitationContext, ElicitationResult, ElicitationSchema, ElicitationSchemaField, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, InfiniteSessionConfig, InputOptions,
|
|
8
|
+
export { defineTool, approveAll, convertMcpCallToolResult, createSessionFsAdapter, SYSTEM_PROMPT_SECTIONS, } from "./types.js";
|
|
9
|
+
export type { CommandContext, CommandDefinition, CommandHandler, ConnectionState, CopilotClientOptions, CustomAgentConfig, ElicitationFieldValue, ElicitationHandler, ElicitationParams, ElicitationContext, ElicitationResult, ElicitationSchema, ElicitationSchemaField, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, InfiniteSessionConfig, InputOptions, MCPStdioServerConfig, MCPHTTPServerConfig, MCPServerConfig, DefaultAgentConfig, MessageOptions, ModelBilling, ModelCapabilities, ModelCapabilitiesOverride, ModelInfo, ModelPolicy, PermissionHandler, PermissionRequest, PermissionRequestResult, ProviderConfig, ResumeSessionConfig, SectionOverride, SectionOverrideAction, SectionTransformFn, SessionCapabilities, SessionConfig, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionLifecycleEvent, SessionLifecycleEventType, SessionLifecycleHandler, SessionContext, SessionListFilter, SessionMetadata, SessionUiApi, SessionFsConfig, SessionFsProvider, SessionFsFileInfo, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageCustomizeConfig, SystemMessageReplaceConfig, SystemPromptSection, TelemetryConfig, TraceContext, TraceContextProvider, Tool, ToolHandler, ToolInvocation, ToolResultObject, TypedSessionEventHandler, TypedSessionLifecycleHandler, ZodSchema, } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { CopilotClient } from "./client.js";
|
|
2
2
|
import { CopilotSession } from "./session.js";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
defineTool,
|
|
5
|
+
approveAll,
|
|
6
|
+
convertMcpCallToolResult,
|
|
7
|
+
createSessionFsAdapter,
|
|
8
|
+
SYSTEM_PROMPT_SECTIONS
|
|
9
|
+
} from "./types.js";
|
|
4
10
|
export {
|
|
5
11
|
CopilotClient,
|
|
6
12
|
CopilotSession,
|
|
7
13
|
SYSTEM_PROMPT_SECTIONS,
|
|
8
14
|
approveAll,
|
|
15
|
+
convertMcpCallToolResult,
|
|
16
|
+
createSessionFsAdapter,
|
|
9
17
|
defineTool
|
|
10
18
|
};
|
package/dist/session.js
CHANGED
|
@@ -100,7 +100,8 @@ class CopilotSession {
|
|
|
100
100
|
sessionId: this.sessionId,
|
|
101
101
|
prompt: options.prompt,
|
|
102
102
|
attachments: options.attachments,
|
|
103
|
-
mode: options.mode
|
|
103
|
+
mode: options.mode,
|
|
104
|
+
requestHeaders: options.requestHeaders
|
|
104
105
|
});
|
|
105
106
|
return response.messageId;
|
|
106
107
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { SessionFsHandler, SessionFsStatResult, SessionFsReaddirWithTypesEntry } from "./generated/rpc.js";
|
|
2
|
+
/**
|
|
3
|
+
* File metadata returned by {@link SessionFsProvider.stat}.
|
|
4
|
+
* Same shape as the generated {@link SessionFsStatResult} but without the
|
|
5
|
+
* `error` field, since providers signal errors by throwing.
|
|
6
|
+
*/
|
|
7
|
+
export type SessionFsFileInfo = Omit<SessionFsStatResult, "error">;
|
|
8
|
+
/**
|
|
9
|
+
* Interface for session filesystem providers. Implementors use idiomatic
|
|
10
|
+
* TypeScript patterns: throw on error, return values directly. Use
|
|
11
|
+
* {@link createSessionFsAdapter} to convert a provider into the
|
|
12
|
+
* {@link SessionFsHandler} expected by the SDK.
|
|
13
|
+
*
|
|
14
|
+
* Errors with a `code` property of `"ENOENT"` are mapped to the ENOENT
|
|
15
|
+
* error code; all others map to UNKNOWN.
|
|
16
|
+
*/
|
|
17
|
+
export interface SessionFsProvider {
|
|
18
|
+
/** Reads the full content of a file. Throw if the file does not exist. */
|
|
19
|
+
readFile(path: string): Promise<string>;
|
|
20
|
+
/** Writes content to a file, creating parent directories if needed. */
|
|
21
|
+
writeFile(path: string, content: string, mode?: number): Promise<void>;
|
|
22
|
+
/** Appends content to a file, creating parent directories if needed. */
|
|
23
|
+
appendFile(path: string, content: string, mode?: number): Promise<void>;
|
|
24
|
+
/** Checks whether a path exists. */
|
|
25
|
+
exists(path: string): Promise<boolean>;
|
|
26
|
+
/** Gets metadata about a file or directory. Throw if it does not exist. */
|
|
27
|
+
stat(path: string): Promise<SessionFsFileInfo>;
|
|
28
|
+
/** Creates a directory. If recursive is true, creates parents as needed. */
|
|
29
|
+
mkdir(path: string, recursive: boolean, mode?: number): Promise<void>;
|
|
30
|
+
/** Lists entry names in a directory. Throw if it does not exist. */
|
|
31
|
+
readdir(path: string): Promise<string[]>;
|
|
32
|
+
/** Lists entries with type info. Throw if the directory does not exist. */
|
|
33
|
+
readdirWithTypes(path: string): Promise<SessionFsReaddirWithTypesEntry[]>;
|
|
34
|
+
/** Removes a file or directory. If force is true, do not throw on ENOENT. */
|
|
35
|
+
rm(path: string, recursive: boolean, force: boolean): Promise<void>;
|
|
36
|
+
/** Renames/moves a file or directory. */
|
|
37
|
+
rename(src: string, dest: string): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Wraps a {@link SessionFsProvider} into the {@link SessionFsHandler}
|
|
41
|
+
* interface expected by the SDK, converting thrown errors into
|
|
42
|
+
* {@link SessionFsError} results.
|
|
43
|
+
*/
|
|
44
|
+
export declare function createSessionFsAdapter(provider: SessionFsProvider): SessionFsHandler;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
function createSessionFsAdapter(provider) {
|
|
2
|
+
return {
|
|
3
|
+
readFile: async ({ path }) => {
|
|
4
|
+
try {
|
|
5
|
+
const content = await provider.readFile(path);
|
|
6
|
+
return { content };
|
|
7
|
+
} catch (err) {
|
|
8
|
+
return { content: "", error: toSessionFsError(err) };
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
writeFile: async ({ path, content, mode }) => {
|
|
12
|
+
try {
|
|
13
|
+
await provider.writeFile(path, content, mode);
|
|
14
|
+
return void 0;
|
|
15
|
+
} catch (err) {
|
|
16
|
+
return toSessionFsError(err);
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
appendFile: async ({ path, content, mode }) => {
|
|
20
|
+
try {
|
|
21
|
+
await provider.appendFile(path, content, mode);
|
|
22
|
+
return void 0;
|
|
23
|
+
} catch (err) {
|
|
24
|
+
return toSessionFsError(err);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
exists: async ({ path }) => {
|
|
28
|
+
try {
|
|
29
|
+
return { exists: await provider.exists(path) };
|
|
30
|
+
} catch {
|
|
31
|
+
return { exists: false };
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
stat: async ({ path }) => {
|
|
35
|
+
try {
|
|
36
|
+
return await provider.stat(path);
|
|
37
|
+
} catch (err) {
|
|
38
|
+
return {
|
|
39
|
+
isFile: false,
|
|
40
|
+
isDirectory: false,
|
|
41
|
+
size: 0,
|
|
42
|
+
mtime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
43
|
+
birthtime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
44
|
+
error: toSessionFsError(err)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
mkdir: async ({ path, recursive, mode }) => {
|
|
49
|
+
try {
|
|
50
|
+
await provider.mkdir(path, recursive ?? false, mode);
|
|
51
|
+
return void 0;
|
|
52
|
+
} catch (err) {
|
|
53
|
+
return toSessionFsError(err);
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
readdir: async ({ path }) => {
|
|
57
|
+
try {
|
|
58
|
+
const entries = await provider.readdir(path);
|
|
59
|
+
return { entries };
|
|
60
|
+
} catch (err) {
|
|
61
|
+
return { entries: [], error: toSessionFsError(err) };
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
readdirWithTypes: async ({ path }) => {
|
|
65
|
+
try {
|
|
66
|
+
const entries = await provider.readdirWithTypes(path);
|
|
67
|
+
return { entries };
|
|
68
|
+
} catch (err) {
|
|
69
|
+
return { entries: [], error: toSessionFsError(err) };
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
rm: async ({ path, recursive, force }) => {
|
|
73
|
+
try {
|
|
74
|
+
await provider.rm(path, recursive ?? false, force ?? false);
|
|
75
|
+
return void 0;
|
|
76
|
+
} catch (err) {
|
|
77
|
+
return toSessionFsError(err);
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
rename: async ({ src, dest }) => {
|
|
81
|
+
try {
|
|
82
|
+
await provider.rename(src, dest);
|
|
83
|
+
return void 0;
|
|
84
|
+
} catch (err) {
|
|
85
|
+
return toSessionFsError(err);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function toSessionFsError(err) {
|
|
91
|
+
const e = err;
|
|
92
|
+
const code = e.code === "ENOENT" ? "ENOENT" : "UNKNOWN";
|
|
93
|
+
return { code, message: e.message ?? String(err) };
|
|
94
|
+
}
|
|
95
|
+
export {
|
|
96
|
+
createSessionFsAdapter
|
|
97
|
+
};
|
package/dist/types.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Type definitions for the Copilot SDK
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
4
|
+
import type { SessionFsProvider } from "./sessionFsProvider.js";
|
|
5
5
|
import type { SessionEvent as GeneratedSessionEvent } from "./generated/session-events.js";
|
|
6
6
|
import type { CopilotSession } from "./session.js";
|
|
7
7
|
export type SessionEvent = GeneratedSessionEvent;
|
|
8
|
-
export type {
|
|
8
|
+
export type { SessionFsProvider } from "./sessionFsProvider.js";
|
|
9
|
+
export { createSessionFsAdapter } from "./sessionFsProvider.js";
|
|
10
|
+
export type { SessionFsFileInfo } from "./sessionFsProvider.js";
|
|
9
11
|
/**
|
|
10
12
|
* Options for creating a CopilotClient
|
|
11
13
|
*/
|
|
@@ -176,6 +178,40 @@ export type ToolResultObject = {
|
|
|
176
178
|
toolTelemetry?: Record<string, unknown>;
|
|
177
179
|
};
|
|
178
180
|
export type ToolResult = string | ToolResultObject;
|
|
181
|
+
/**
|
|
182
|
+
* Content block types within an MCP CallToolResult.
|
|
183
|
+
*/
|
|
184
|
+
type McpCallToolResultTextContent = {
|
|
185
|
+
type: "text";
|
|
186
|
+
text: string;
|
|
187
|
+
};
|
|
188
|
+
type McpCallToolResultImageContent = {
|
|
189
|
+
type: "image";
|
|
190
|
+
data: string;
|
|
191
|
+
mimeType: string;
|
|
192
|
+
};
|
|
193
|
+
type McpCallToolResultResourceContent = {
|
|
194
|
+
type: "resource";
|
|
195
|
+
resource: {
|
|
196
|
+
uri: string;
|
|
197
|
+
mimeType?: string;
|
|
198
|
+
text?: string;
|
|
199
|
+
blob?: string;
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
type McpCallToolResultContent = McpCallToolResultTextContent | McpCallToolResultImageContent | McpCallToolResultResourceContent;
|
|
203
|
+
/**
|
|
204
|
+
* MCP-compatible CallToolResult type. Can be passed to
|
|
205
|
+
* {@link convertMcpCallToolResult} to produce a {@link ToolResultObject}.
|
|
206
|
+
*/
|
|
207
|
+
type McpCallToolResult = {
|
|
208
|
+
content: McpCallToolResultContent[];
|
|
209
|
+
isError?: boolean;
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* Converts an MCP CallToolResult into the SDK's ToolResultObject format.
|
|
213
|
+
*/
|
|
214
|
+
export declare function convertMcpCallToolResult(callResult: McpCallToolResult): ToolResultObject;
|
|
179
215
|
export interface ToolInvocation {
|
|
180
216
|
sessionId: string;
|
|
181
217
|
toolCallId: string;
|
|
@@ -532,18 +568,18 @@ export type SystemMessageConfig = SystemMessageAppendConfig | SystemMessageRepla
|
|
|
532
568
|
* Permission request types from the server
|
|
533
569
|
*/
|
|
534
570
|
export interface PermissionRequest {
|
|
535
|
-
kind: "shell" | "write" | "mcp" | "read" | "url" | "custom-tool";
|
|
571
|
+
kind: "shell" | "write" | "mcp" | "read" | "url" | "custom-tool" | "memory" | "hook";
|
|
536
572
|
toolCallId?: string;
|
|
537
|
-
[key: string]: unknown;
|
|
538
573
|
}
|
|
539
|
-
import type {
|
|
540
|
-
export type PermissionRequestResult =
|
|
574
|
+
import type { PermissionDecisionRequest } from "./generated/rpc.js";
|
|
575
|
+
export type PermissionRequestResult = PermissionDecisionRequest["result"] | {
|
|
541
576
|
kind: "no-result";
|
|
542
577
|
};
|
|
543
578
|
export type PermissionHandler = (request: PermissionRequest, invocation: {
|
|
544
579
|
sessionId: string;
|
|
545
580
|
}) => Promise<PermissionRequestResult> | PermissionRequestResult;
|
|
546
581
|
export declare const approveAll: PermissionHandler;
|
|
582
|
+
export declare const defaultJoinSessionPermissionHandler: PermissionHandler;
|
|
547
583
|
/**
|
|
548
584
|
* Request for user input from the agent (enables ask_user tool)
|
|
549
585
|
*/
|
|
@@ -756,8 +792,8 @@ interface MCPServerConfigBase {
|
|
|
756
792
|
*/
|
|
757
793
|
tools: string[];
|
|
758
794
|
/**
|
|
759
|
-
* Indicates "
|
|
760
|
-
* If not specified, defaults to "
|
|
795
|
+
* Indicates the server type: "stdio" for local/subprocess servers, "http"/"sse" for remote servers.
|
|
796
|
+
* If not specified, defaults to "stdio".
|
|
761
797
|
*/
|
|
762
798
|
type?: string;
|
|
763
799
|
/**
|
|
@@ -768,7 +804,7 @@ interface MCPServerConfigBase {
|
|
|
768
804
|
/**
|
|
769
805
|
* Configuration for a local/stdio MCP server.
|
|
770
806
|
*/
|
|
771
|
-
export interface
|
|
807
|
+
export interface MCPStdioServerConfig extends MCPServerConfigBase {
|
|
772
808
|
type?: "local" | "stdio";
|
|
773
809
|
command: string;
|
|
774
810
|
args: string[];
|
|
@@ -781,7 +817,7 @@ export interface MCPLocalServerConfig extends MCPServerConfigBase {
|
|
|
781
817
|
/**
|
|
782
818
|
* Configuration for a remote MCP server (HTTP or SSE).
|
|
783
819
|
*/
|
|
784
|
-
export interface
|
|
820
|
+
export interface MCPHTTPServerConfig extends MCPServerConfigBase {
|
|
785
821
|
type: "http" | "sse";
|
|
786
822
|
/**
|
|
787
823
|
* URL of the remote server.
|
|
@@ -795,7 +831,7 @@ export interface MCPRemoteServerConfig extends MCPServerConfigBase {
|
|
|
795
831
|
/**
|
|
796
832
|
* Union type for MCP server configurations.
|
|
797
833
|
*/
|
|
798
|
-
export type MCPServerConfig =
|
|
834
|
+
export type MCPServerConfig = MCPStdioServerConfig | MCPHTTPServerConfig;
|
|
799
835
|
/**
|
|
800
836
|
* Configuration for a custom agent.
|
|
801
837
|
*/
|
|
@@ -830,6 +866,28 @@ export interface CustomAgentConfig {
|
|
|
830
866
|
* @default true
|
|
831
867
|
*/
|
|
832
868
|
infer?: boolean;
|
|
869
|
+
/**
|
|
870
|
+
* List of skill names to preload into this agent's context.
|
|
871
|
+
* When set, the full content of each listed skill is eagerly injected into
|
|
872
|
+
* the agent's context at startup. Skills are resolved by name from the
|
|
873
|
+
* session's configured skill directories (`skillDirectories`).
|
|
874
|
+
* When omitted, no skills are injected (opt-in model).
|
|
875
|
+
*/
|
|
876
|
+
skills?: string[];
|
|
877
|
+
}
|
|
878
|
+
/**
|
|
879
|
+
* Configuration for the default agent (the built-in agent that handles
|
|
880
|
+
* turns when no custom agent is selected).
|
|
881
|
+
* Use this to control tool visibility for the default agent independently of custom sub-agents.
|
|
882
|
+
*/
|
|
883
|
+
export interface DefaultAgentConfig {
|
|
884
|
+
/**
|
|
885
|
+
* List of tool names to exclude from the default agent.
|
|
886
|
+
* These tools remain available to custom sub-agents that reference them in their `tools` array.
|
|
887
|
+
* Use this to register tools that should only be accessed via delegation to sub-agents,
|
|
888
|
+
* keeping the default agent's context clean.
|
|
889
|
+
*/
|
|
890
|
+
excludedTools?: string[];
|
|
833
891
|
}
|
|
834
892
|
/**
|
|
835
893
|
* Configuration for infinite sessions with automatic context compaction and workspace persistence.
|
|
@@ -956,6 +1014,16 @@ export interface SessionConfig {
|
|
|
956
1014
|
*/
|
|
957
1015
|
workingDirectory?: string;
|
|
958
1016
|
streaming?: boolean;
|
|
1017
|
+
/**
|
|
1018
|
+
* Include sub-agent streaming events in the event stream. When true, streaming
|
|
1019
|
+
* delta events from sub-agents (e.g., `assistant.message_delta`,
|
|
1020
|
+
* `assistant.reasoning_delta`, `assistant.streaming_delta` with `agentId` set)
|
|
1021
|
+
* are forwarded to this connection. When false, only non-streaming sub-agent
|
|
1022
|
+
* events and `subagent.*` lifecycle events are forwarded; streaming deltas from
|
|
1023
|
+
* sub-agents are suppressed.
|
|
1024
|
+
* @default true
|
|
1025
|
+
*/
|
|
1026
|
+
includeSubAgentStreamingEvents?: boolean;
|
|
959
1027
|
/**
|
|
960
1028
|
* MCP server configurations for the session.
|
|
961
1029
|
* Keys are server names, values are server configurations.
|
|
@@ -965,6 +1033,13 @@ export interface SessionConfig {
|
|
|
965
1033
|
* Custom agent configurations for the session.
|
|
966
1034
|
*/
|
|
967
1035
|
customAgents?: CustomAgentConfig[];
|
|
1036
|
+
/**
|
|
1037
|
+
* Configuration for the default agent (the built-in agent that handles
|
|
1038
|
+
* turns when no custom agent is selected).
|
|
1039
|
+
* Use `excludedTools` to hide specific tools from the default agent while keeping
|
|
1040
|
+
* them available to custom sub-agents.
|
|
1041
|
+
*/
|
|
1042
|
+
defaultAgent?: DefaultAgentConfig;
|
|
968
1043
|
/**
|
|
969
1044
|
* Name of the custom agent to activate when the session starts.
|
|
970
1045
|
* Must match the `name` of one of the agents in `customAgents`.
|
|
@@ -999,12 +1074,12 @@ export interface SessionConfig {
|
|
|
999
1074
|
* Supplies a handler for session filesystem operations. This takes effect
|
|
1000
1075
|
* only if {@link CopilotClientOptions.sessionFs} is configured.
|
|
1001
1076
|
*/
|
|
1002
|
-
createSessionFsHandler?: (session: CopilotSession) =>
|
|
1077
|
+
createSessionFsHandler?: (session: CopilotSession) => SessionFsProvider;
|
|
1003
1078
|
}
|
|
1004
1079
|
/**
|
|
1005
1080
|
* Configuration for resuming a session
|
|
1006
1081
|
*/
|
|
1007
|
-
export type ResumeSessionConfig = Pick<SessionConfig, "clientName" | "model" | "tools" | "commands" | "systemMessage" | "availableTools" | "excludedTools" | "provider" | "modelCapabilities" | "streaming" | "reasoningEffort" | "onPermissionRequest" | "onUserInputRequest" | "onElicitationRequest" | "hooks" | "workingDirectory" | "configDir" | "enableConfigDiscovery" | "mcpServers" | "customAgents" | "agent" | "skillDirectories" | "disabledSkills" | "infiniteSessions" | "onEvent" | "createSessionFsHandler"> & {
|
|
1082
|
+
export type ResumeSessionConfig = Pick<SessionConfig, "clientName" | "model" | "tools" | "commands" | "systemMessage" | "availableTools" | "excludedTools" | "provider" | "modelCapabilities" | "streaming" | "includeSubAgentStreamingEvents" | "reasoningEffort" | "onPermissionRequest" | "onUserInputRequest" | "onElicitationRequest" | "hooks" | "workingDirectory" | "configDir" | "enableConfigDiscovery" | "mcpServers" | "customAgents" | "defaultAgent" | "agent" | "skillDirectories" | "disabledSkills" | "infiniteSessions" | "onEvent" | "createSessionFsHandler"> & {
|
|
1008
1083
|
/**
|
|
1009
1084
|
* When true, skips emitting the session.resume event.
|
|
1010
1085
|
* Useful for reconnecting to a session without triggering resume-related side effects.
|
|
@@ -1047,6 +1122,10 @@ export interface ProviderConfig {
|
|
|
1047
1122
|
*/
|
|
1048
1123
|
apiVersion?: string;
|
|
1049
1124
|
};
|
|
1125
|
+
/**
|
|
1126
|
+
* Custom HTTP headers to include in outbound provider requests.
|
|
1127
|
+
*/
|
|
1128
|
+
headers?: Record<string, string>;
|
|
1050
1129
|
}
|
|
1051
1130
|
/**
|
|
1052
1131
|
* Options for sending a message to a session
|
|
@@ -1094,6 +1173,10 @@ export interface MessageOptions {
|
|
|
1094
1173
|
* - "immediate": Send immediately
|
|
1095
1174
|
*/
|
|
1096
1175
|
mode?: "enqueue" | "immediate";
|
|
1176
|
+
/**
|
|
1177
|
+
* Custom HTTP headers to include in outbound model requests for this turn.
|
|
1178
|
+
*/
|
|
1179
|
+
requestHeaders?: Record<string, string>;
|
|
1097
1180
|
}
|
|
1098
1181
|
/**
|
|
1099
1182
|
* All possible event type strings from SessionEvent
|
package/dist/types.js
CHANGED
|
@@ -1,3 +1,45 @@
|
|
|
1
|
+
import { createSessionFsAdapter } from "./sessionFsProvider.js";
|
|
2
|
+
function convertMcpCallToolResult(callResult) {
|
|
3
|
+
const textParts = [];
|
|
4
|
+
const binaryResults = [];
|
|
5
|
+
for (const block of callResult.content) {
|
|
6
|
+
switch (block.type) {
|
|
7
|
+
case "text":
|
|
8
|
+
if (typeof block.text === "string") {
|
|
9
|
+
textParts.push(block.text);
|
|
10
|
+
}
|
|
11
|
+
break;
|
|
12
|
+
case "image":
|
|
13
|
+
if (typeof block.data === "string" && block.data && typeof block.mimeType === "string") {
|
|
14
|
+
binaryResults.push({
|
|
15
|
+
data: block.data,
|
|
16
|
+
mimeType: block.mimeType,
|
|
17
|
+
type: "image"
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
break;
|
|
21
|
+
case "resource": {
|
|
22
|
+
if (block.resource?.text) {
|
|
23
|
+
textParts.push(block.resource.text);
|
|
24
|
+
}
|
|
25
|
+
if (block.resource?.blob) {
|
|
26
|
+
binaryResults.push({
|
|
27
|
+
data: block.resource.blob,
|
|
28
|
+
mimeType: block.resource.mimeType ?? "application/octet-stream",
|
|
29
|
+
type: "resource",
|
|
30
|
+
description: block.resource.uri
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
textResultForLlm: textParts.join("\n"),
|
|
39
|
+
resultType: callResult.isError ? "failure" : "success",
|
|
40
|
+
...binaryResults.length > 0 ? { binaryResultsForLlm: binaryResults } : {}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
1
43
|
function defineTool(name, config) {
|
|
2
44
|
return { name, ...config };
|
|
3
45
|
}
|
|
@@ -16,8 +58,14 @@ const SYSTEM_PROMPT_SECTIONS = {
|
|
|
16
58
|
}
|
|
17
59
|
};
|
|
18
60
|
const approveAll = () => ({ kind: "approved" });
|
|
61
|
+
const defaultJoinSessionPermissionHandler = () => ({
|
|
62
|
+
kind: "no-result"
|
|
63
|
+
});
|
|
19
64
|
export {
|
|
20
65
|
SYSTEM_PROMPT_SECTIONS,
|
|
21
66
|
approveAll,
|
|
67
|
+
convertMcpCallToolResult,
|
|
68
|
+
createSessionFsAdapter,
|
|
69
|
+
defaultJoinSessionPermissionHandler,
|
|
22
70
|
defineTool
|
|
23
71
|
};
|
package/docs/agent-author.md
CHANGED
|
@@ -18,6 +18,7 @@ For user-scoped extensions (persist across all repos), add `location: "user"`.
|
|
|
18
18
|
### Step 2: Edit the extension file
|
|
19
19
|
|
|
20
20
|
Modify the generated `extension.mjs` using `edit` or `create` tools. The file must:
|
|
21
|
+
|
|
21
22
|
- Be named `extension.mjs` (only `.mjs` is supported)
|
|
22
23
|
- Use ES module syntax (`import`/`export`)
|
|
23
24
|
- Call `joinSession({ ... })`
|
|
@@ -48,6 +49,7 @@ Check that the extension loaded successfully and isn't marked as "failed".
|
|
|
48
49
|
```
|
|
49
50
|
|
|
50
51
|
Discovery rules:
|
|
52
|
+
|
|
51
53
|
- The CLI scans `.github/extensions/` relative to the git root
|
|
52
54
|
- It also scans the user's copilot config extensions directory
|
|
53
55
|
- Only immediate subdirectories are checked (not recursive)
|
|
@@ -62,8 +64,8 @@ Discovery rules:
|
|
|
62
64
|
import { joinSession } from "@github/copilot-sdk/extension";
|
|
63
65
|
|
|
64
66
|
await joinSession({
|
|
65
|
-
tools: [],
|
|
66
|
-
hooks: {},
|
|
67
|
+
tools: [], // Optional — custom tools
|
|
68
|
+
hooks: {}, // Optional — lifecycle hooks
|
|
67
69
|
});
|
|
68
70
|
```
|
|
69
71
|
|
|
@@ -74,9 +76,10 @@ await joinSession({
|
|
|
74
76
|
```js
|
|
75
77
|
tools: [
|
|
76
78
|
{
|
|
77
|
-
name: "tool_name",
|
|
79
|
+
name: "tool_name", // Required. Must be globally unique across all extensions.
|
|
78
80
|
description: "What it does", // Required. Shown to the agent in tool descriptions.
|
|
79
|
-
parameters: {
|
|
81
|
+
parameters: {
|
|
82
|
+
// Optional. JSON Schema for the arguments.
|
|
80
83
|
type: "object",
|
|
81
84
|
properties: {
|
|
82
85
|
arg1: { type: "string", description: "..." },
|
|
@@ -96,10 +99,11 @@ tools: [
|
|
|
96
99
|
return `Result: ${args.arg1}`;
|
|
97
100
|
},
|
|
98
101
|
},
|
|
99
|
-
]
|
|
102
|
+
];
|
|
100
103
|
```
|
|
101
104
|
|
|
102
105
|
**Constraints:**
|
|
106
|
+
|
|
103
107
|
- Tool names must be unique across ALL loaded extensions. Collisions cause the second extension to fail to load.
|
|
104
108
|
- Handler must return a string or `{ textResultForLlm: string, resultType?: string }`.
|
|
105
109
|
- Handler receives `(args, invocation)` — the second argument has `sessionId`, `toolCallId`, `toolName`.
|
|
@@ -195,6 +199,7 @@ After `joinSession()`, the returned `session` provides:
|
|
|
195
199
|
### session.send(options)
|
|
196
200
|
|
|
197
201
|
Send a message programmatically:
|
|
202
|
+
|
|
198
203
|
```js
|
|
199
204
|
await session.send({ prompt: "Analyze the test results." });
|
|
200
205
|
await session.send({
|
|
@@ -206,6 +211,7 @@ await session.send({
|
|
|
206
211
|
### session.sendAndWait(options, timeout?)
|
|
207
212
|
|
|
208
213
|
Send and block until the agent finishes (resolves on `session.idle`):
|
|
214
|
+
|
|
209
215
|
```js
|
|
210
216
|
const response = await session.sendAndWait({ prompt: "What is 2+2?" });
|
|
211
217
|
// response?.data.content contains the agent's reply
|
|
@@ -214,6 +220,7 @@ const response = await session.sendAndWait({ prompt: "What is 2+2?" });
|
|
|
214
220
|
### session.log(message, options?)
|
|
215
221
|
|
|
216
222
|
Log to the CLI timeline:
|
|
223
|
+
|
|
217
224
|
```js
|
|
218
225
|
await session.log("Extension ready");
|
|
219
226
|
await session.log("Rate limit approaching", { level: "warning" });
|
|
@@ -224,6 +231,7 @@ await session.log("Processing...", { ephemeral: true }); // transient, not persi
|
|
|
224
231
|
### session.on(eventType, handler)
|
|
225
232
|
|
|
226
233
|
Subscribe to session events. Returns an unsubscribe function.
|
|
234
|
+
|
|
227
235
|
```js
|
|
228
236
|
const unsub = session.on("tool.execution_complete", (event) => {
|
|
229
237
|
// event.data.toolName, event.data.success, event.data.result
|
|
@@ -232,16 +240,16 @@ const unsub = session.on("tool.execution_complete", (event) => {
|
|
|
232
240
|
|
|
233
241
|
### Key Event Types
|
|
234
242
|
|
|
235
|
-
| Event
|
|
236
|
-
|
|
237
|
-
| `assistant.message`
|
|
238
|
-
| `tool.execution_start`
|
|
243
|
+
| Event | Key Data Fields |
|
|
244
|
+
| ------------------------- | ------------------------------------------------------ |
|
|
245
|
+
| `assistant.message` | `content`, `messageId` |
|
|
246
|
+
| `tool.execution_start` | `toolCallId`, `toolName`, `arguments` |
|
|
239
247
|
| `tool.execution_complete` | `toolCallId`, `toolName`, `success`, `result`, `error` |
|
|
240
|
-
| `user.message`
|
|
241
|
-
| `session.idle`
|
|
242
|
-
| `session.error`
|
|
243
|
-
| `permission.requested`
|
|
244
|
-
| `session.shutdown`
|
|
248
|
+
| `user.message` | `content`, `attachments`, `source` |
|
|
249
|
+
| `session.idle` | `backgroundTasks` |
|
|
250
|
+
| `session.error` | `errorType`, `message`, `stack` |
|
|
251
|
+
| `permission.requested` | `requestId`, `permissionRequest.kind` |
|
|
252
|
+
| `session.shutdown` | `shutdownType`, `totalPremiumRequests` |
|
|
245
253
|
|
|
246
254
|
### session.workspacePath
|
|
247
255
|
|