xcode-copilot-server 2.2.0 → 3.0.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/README.md +83 -26
- package/config.json5 +13 -8
- package/dist/cli-validators.js +2 -2
- package/dist/cli-validators.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/conversation-manager.d.ts +2 -1
- package/dist/conversation-manager.js +20 -1
- package/dist/conversation-manager.js.map +1 -1
- package/dist/handlers/responses/streaming.d.ts +6 -0
- package/dist/handlers/responses/streaming.js +265 -0
- package/dist/handlers/responses/streaming.js.map +1 -0
- package/dist/handlers/responses/tool-result-handler.d.ts +4 -0
- package/dist/handlers/responses/tool-result-handler.js +9 -0
- package/dist/handlers/responses/tool-result-handler.js.map +1 -0
- package/dist/handlers/responses.d.ts +4 -0
- package/dist/handlers/responses.js +164 -0
- package/dist/handlers/responses.js.map +1 -0
- package/dist/handlers/streaming-utils.d.ts +1 -0
- package/dist/handlers/streaming-utils.js +3 -0
- package/dist/handlers/streaming-utils.js.map +1 -1
- package/dist/index.js +23 -108
- package/dist/index.js.map +1 -1
- package/dist/providers/claude/count-tokens.d.ts +3 -0
- package/dist/providers/claude/count-tokens.js +72 -0
- package/dist/providers/claude/count-tokens.js.map +1 -0
- package/dist/providers/claude/handler.d.ts +4 -0
- package/dist/providers/claude/handler.js +150 -0
- package/dist/providers/claude/handler.js.map +1 -0
- package/dist/providers/claude/prompt.d.ts +2 -0
- package/dist/providers/claude/prompt.js +52 -0
- package/dist/providers/claude/prompt.js.map +1 -0
- package/dist/providers/claude/provider.d.ts +5 -0
- package/dist/providers/claude/provider.js +28 -0
- package/dist/providers/claude/provider.js.map +1 -0
- package/dist/providers/claude/schemas.d.ts +140 -0
- package/dist/providers/claude/schemas.js +58 -0
- package/dist/providers/claude/schemas.js.map +1 -0
- package/dist/providers/claude/streaming.d.ts +6 -0
- package/dist/providers/claude/streaming.js +116 -0
- package/dist/providers/claude/streaming.js.map +1 -0
- package/dist/providers/claude/tool-results.d.ts +4 -0
- package/dist/providers/claude/tool-results.js +19 -0
- package/dist/providers/claude/tool-results.js.map +1 -0
- package/dist/providers/codex/handler.d.ts +4 -0
- package/dist/providers/codex/handler.js +164 -0
- package/dist/providers/codex/handler.js.map +1 -0
- package/dist/providers/codex/prompt.d.ts +4 -0
- package/dist/providers/codex/prompt.js +58 -0
- package/dist/providers/codex/prompt.js.map +1 -0
- package/dist/providers/codex/provider.d.ts +5 -0
- package/dist/providers/codex/provider.js +24 -0
- package/dist/providers/codex/provider.js.map +1 -0
- package/dist/providers/codex/schemas.d.ts +122 -0
- package/dist/providers/codex/schemas.js +55 -0
- package/dist/providers/codex/schemas.js.map +1 -0
- package/dist/providers/codex/streaming.d.ts +9 -0
- package/dist/providers/codex/streaming.js +172 -0
- package/dist/providers/codex/streaming.js.map +1 -0
- package/dist/providers/codex/tool-results.d.ts +4 -0
- package/dist/providers/codex/tool-results.js +9 -0
- package/dist/providers/codex/tool-results.js.map +1 -0
- package/dist/providers/codex.d.ts +5 -0
- package/dist/providers/codex.js +24 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/providers/index.d.ts +6 -1
- package/dist/providers/index.js +5 -3
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/openai/handler.d.ts +4 -0
- package/dist/providers/openai/handler.js +120 -0
- package/dist/providers/openai/handler.js.map +1 -0
- package/dist/providers/openai/models.d.ts +3 -0
- package/dist/providers/openai/models.js +28 -0
- package/dist/providers/openai/models.js.map +1 -0
- package/dist/providers/openai/prompt.d.ts +3 -0
- package/dist/providers/openai/prompt.js +38 -0
- package/dist/providers/openai/prompt.js.map +1 -0
- package/dist/providers/openai/provider.d.ts +5 -0
- package/dist/providers/openai/provider.js +25 -0
- package/dist/providers/openai/provider.js.map +1 -0
- package/dist/providers/openai/schemas.d.ts +98 -0
- package/dist/providers/openai/schemas.js +76 -0
- package/dist/providers/openai/schemas.js.map +1 -0
- package/dist/providers/openai/streaming.d.ts +4 -0
- package/dist/providers/openai/streaming.js +121 -0
- package/dist/providers/openai/streaming.js.map +1 -0
- package/dist/providers/shared/errors.d.ts +5 -0
- package/dist/providers/shared/errors.js +10 -0
- package/dist/providers/shared/errors.js.map +1 -0
- package/dist/providers/shared/model-resolver.d.ts +3 -0
- package/dist/providers/shared/model-resolver.js +45 -0
- package/dist/providers/shared/model-resolver.js.map +1 -0
- package/dist/providers/shared/prompt-utils.d.ts +1 -0
- package/dist/providers/shared/prompt-utils.js +15 -0
- package/dist/providers/shared/prompt-utils.js.map +1 -0
- package/dist/providers/shared/session-config.d.ts +15 -0
- package/dist/providers/shared/session-config.js +98 -0
- package/dist/providers/shared/session-config.js.map +1 -0
- package/dist/providers/shared/streaming-core.d.ts +19 -0
- package/dist/providers/shared/streaming-core.js +176 -0
- package/dist/providers/shared/streaming-core.js.map +1 -0
- package/dist/providers/shared/streaming-utils.d.ts +10 -0
- package/dist/providers/shared/streaming-utils.js +28 -0
- package/dist/providers/shared/streaming-utils.js.map +1 -0
- package/dist/schemas/config.d.ts +19 -1
- package/dist/schemas/config.js +2 -1
- package/dist/schemas/config.js.map +1 -1
- package/dist/schemas/responses.d.ts +122 -0
- package/dist/schemas/responses.js +54 -0
- package/dist/schemas/responses.js.map +1 -0
- package/dist/server.js +1 -2
- package/dist/server.js.map +1 -1
- package/dist/settings-patcher/anthropic.d.ts +5 -0
- package/dist/{settings-patcher.js → settings-patcher/anthropic.js} +3 -7
- package/dist/settings-patcher/anthropic.js.map +1 -0
- package/dist/settings-patcher/claude.d.ts +5 -0
- package/dist/settings-patcher/claude.js +75 -0
- package/dist/settings-patcher/claude.js.map +1 -0
- package/dist/settings-patcher/codex.d.ts +23 -0
- package/dist/settings-patcher/codex.js +114 -0
- package/dist/settings-patcher/codex.js.map +1 -0
- package/dist/settings-patcher/index.d.ts +15 -0
- package/dist/settings-patcher/index.js +9 -0
- package/dist/settings-patcher/index.js.map +1 -0
- package/dist/{settings-patcher.d.ts → settings-patcher/types.d.ts} +1 -5
- package/dist/settings-patcher/types.js +2 -0
- package/dist/settings-patcher/types.js.map +1 -0
- package/dist/startup.d.ts +11 -0
- package/dist/startup.js +154 -0
- package/dist/startup.js.map +1 -0
- package/dist/tool-bridge/constants.d.ts +2 -0
- package/dist/tool-bridge/constants.js +3 -0
- package/dist/tool-bridge/constants.js.map +1 -0
- package/dist/tool-bridge/index.d.ts +1 -0
- package/dist/tool-bridge/index.js +1 -0
- package/dist/tool-bridge/index.js.map +1 -1
- package/dist/tool-bridge/routes.js +2 -1
- package/dist/tool-bridge/routes.js.map +1 -1
- package/dist/tool-bridge/session-lifecycle.js +1 -1
- package/dist/tool-bridge/state.d.ts +1 -1
- package/dist/tool-bridge/tool-cache.d.ts +1 -1
- package/dist/ui.d.ts +7 -0
- package/dist/ui.js +8 -0
- package/dist/ui.js.map +1 -1
- package/dist/utils/responses-prompt.d.ts +4 -0
- package/dist/utils/responses-prompt.js +58 -0
- package/dist/utils/responses-prompt.js.map +1 -0
- package/package.json +1 -1
- package/dist/settings-patcher.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
# xcode-copilot-server [](https://www.npmjs.com/package/xcode-copilot-server)
|
|
2
2
|
|
|
3
|
-
A proxy API server that lets you use GitHub Copilot in Xcode, either as a custom model provider
|
|
3
|
+
A proxy API server that lets you use GitHub Copilot in Xcode, either as a custom model provider or as the backend for Claude Agent and Codex Agent.
|
|
4
4
|
|
|
5
5
|
## Why
|
|
6
6
|
|
|
7
7
|
Xcode 26 added support for third-party LLM providers, but it only supports ChatGPT and Claude out of the box. If you have a GitHub Copilot subscription, there's no built-in way to use it.
|
|
8
8
|
|
|
9
|
-
This server bridges the gap by wrapping the [GitHub Copilot SDK](https://github.com/github/copilot-sdk) and exposing it as an API that Xcode can talk to. It supports
|
|
9
|
+
This server bridges the gap by wrapping the [GitHub Copilot SDK](https://github.com/github/copilot-sdk) and exposing it as an API that Xcode can talk to. It supports three providers:
|
|
10
10
|
|
|
11
|
-
- **OpenAI
|
|
12
|
-
- **
|
|
11
|
+
- **OpenAI** (default): Exposes an OpenAI-compatible completions API so Xcode can use Copilot as a custom model provider. Xcode handles tool execution directly.
|
|
12
|
+
- **Claude**: Exposes an Anthropic-compatible API so Xcode can use Copilot as the backend for Claude Agent. A built-in tool bridge intercepts tool calls and routes them back to Xcode for execution.
|
|
13
|
+
- **Codex**: Exposes an OpenAI Responses-compatible API so Xcode can use Copilot as the backend for Codex Agent. Same tool bridge as Claude.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
In OpenAI mode, the server also connects to Xcode's built-in MCP tools (via `xcrun mcpbridge`), giving Copilot access to your project's build logs, indexes and other context. This requires Xcode 26.3 or later. Claude and Codex handle MCP internally through their own agents.
|
|
15
16
|
|
|
16
17
|
## Installation
|
|
17
18
|
|
|
@@ -40,29 +41,30 @@ xcode-copilot-server [options]
|
|
|
40
41
|
|
|
41
42
|
Options:
|
|
42
43
|
-p, --port <number> Port to listen on (default: 8080)
|
|
43
|
-
--proxy <provider> API format: openai,
|
|
44
|
+
--proxy <provider> API format: openai, claude, codex (default: openai)
|
|
44
45
|
-l, --log-level <level> Log verbosity (default: info)
|
|
45
46
|
-c, --config <path> Path to config file
|
|
46
47
|
--cwd <path> Working directory for Copilot sessions
|
|
47
|
-
--auto-patch Auto-patch settings
|
|
48
|
+
--auto-patch Auto-patch settings on start, restore on exit
|
|
48
49
|
-v, --version Output the version number
|
|
49
50
|
-h, --help Show help
|
|
50
51
|
|
|
51
52
|
Commands:
|
|
52
|
-
patch-settings Patch
|
|
53
|
-
restore-settings Restore
|
|
53
|
+
patch-settings Patch provider settings and exit (--proxy claude or codex)
|
|
54
|
+
restore-settings Restore provider settings from backup and exit
|
|
54
55
|
```
|
|
55
56
|
|
|
56
57
|
The `--proxy` flag determines which API the server exposes:
|
|
57
58
|
|
|
58
|
-
|
|
|
59
|
-
|
|
60
|
-
| OpenAI
|
|
61
|
-
|
|
|
59
|
+
| Provider | Flag | Routes |
|
|
60
|
+
|----------|----------------------------|-------------------------------------------------------|
|
|
61
|
+
| OpenAI | `--proxy openai` (default) | `GET /v1/models`, `POST /v1/chat/completions` |
|
|
62
|
+
| Claude | `--proxy claude` | `POST /v1/messages`, `POST /v1/messages/count_tokens` |
|
|
63
|
+
| Codex | `--proxy codex` | `POST /v1/responses` |
|
|
62
64
|
|
|
63
65
|
## Xcode integration
|
|
64
66
|
|
|
65
|
-
### OpenAI
|
|
67
|
+
### OpenAI (custom model provider)
|
|
66
68
|
|
|
67
69
|
1. Start the server: `xcode-copilot-server`
|
|
68
70
|
2. Open Xcode and go to Settings > Intelligence > Add a provider
|
|
@@ -72,14 +74,14 @@ The `--proxy` flag determines which API the server exposes:
|
|
|
72
74
|
|
|
73
75
|
To enable tool calling, select the provider and enable "Allow tools" under "Advanced". To connect Xcode's MCP tools (Xcode 26.3+), enable "Xcode Tools" under "Model Context Protocol".
|
|
74
76
|
|
|
75
|
-
###
|
|
77
|
+
### Claude (Claude Agent)
|
|
76
78
|
|
|
77
79
|
1. Open Xcode and go to Settings > Intelligence > Anthropic > Claude Agent
|
|
78
80
|
2. Enable Claude Agent and sign in with an API key (the key can be any random text, since the calls are proxied through the server)
|
|
79
81
|
3. Start the server with `--auto-patch` to automatically configure `settings.json`:
|
|
80
82
|
|
|
81
83
|
```bash
|
|
82
|
-
xcode-copilot-server --proxy
|
|
84
|
+
xcode-copilot-server --proxy claude --auto-patch
|
|
83
85
|
```
|
|
84
86
|
|
|
85
87
|
This creates (or updates) `settings.json` at `~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/` to point to the server, and restores the original file when the server shuts down. If `settings.json` already exists, a backup is saved as `settings.json.backup` and restored on exit.
|
|
@@ -98,21 +100,68 @@ To enable tool calling, select the provider and enable "Allow tools" under "Adva
|
|
|
98
100
|
Set the port to match your `--port` flag (default 8080). The auth token can be any non-empty string. Then start the server without `--auto-patch`:
|
|
99
101
|
|
|
100
102
|
```bash
|
|
101
|
-
xcode-copilot-server --proxy
|
|
103
|
+
xcode-copilot-server --proxy claude
|
|
102
104
|
```
|
|
103
105
|
|
|
104
|
-
You can also use the `patch-settings` and `restore-settings` subcommands to patch or restore
|
|
106
|
+
You can also use the `patch-settings` and `restore-settings` subcommands to patch or restore settings without starting the server:
|
|
105
107
|
|
|
106
108
|
```bash
|
|
107
|
-
xcode-copilot-server patch-settings --port 8080
|
|
108
|
-
xcode-copilot-server restore-settings
|
|
109
|
+
xcode-copilot-server patch-settings --proxy claude --port 8080
|
|
110
|
+
xcode-copilot-server restore-settings --proxy claude
|
|
109
111
|
```
|
|
110
112
|
|
|
111
|
-
The tool bridge is enabled by default
|
|
113
|
+
The tool bridge is enabled by default for Claude (`toolBridge: true` in the config). It intercepts tool calls from the Copilot session and forwards them to Xcode, so Claude Agent can read files, search code, and make edits through the IDE.
|
|
114
|
+
|
|
115
|
+
### Codex (Codex Agent)
|
|
116
|
+
|
|
117
|
+
1. Open Xcode and go to Settings > Intelligence > OpenAI > Codex Agent
|
|
118
|
+
2. Enable Codex Agent and sign in with an API key (the key can be any random text, since the calls are proxied through the server)
|
|
119
|
+
3. Start the server with `--auto-patch` to automatically configure the environment:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
xcode-copilot-server --proxy codex --auto-patch
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
This sets `OPENAI_BASE_URL` and `OPENAI_API_KEY` via `launchctl setenv` so Xcode (and any Codex process it spawns) can reach the server. The original values are backed up and restored when the server shuts down. If Xcode was already running, you might need to restart it so it picks up the new environment variables.
|
|
126
|
+
|
|
127
|
+
Alternatively, you can set the environment variables yourself via `launchctl`:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
launchctl setenv OPENAI_BASE_URL http://localhost:8080/v1
|
|
131
|
+
launchctl setenv OPENAI_API_KEY 12345
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Set the port to match your `--port` flag (default 8080). The API key can be any non-empty string. Then start the server without `--auto-patch`:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
xcode-copilot-server --proxy codex
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
To restore the original values when you're done:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
launchctl unsetenv OPENAI_BASE_URL
|
|
144
|
+
launchctl unsetenv OPENAI_API_KEY
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
You can also use the `patch-settings` and `restore-settings` subcommands to do this without starting the server:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
xcode-copilot-server patch-settings --proxy codex --port 8080
|
|
151
|
+
xcode-copilot-server restore-settings --proxy codex
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The tool bridge works the same way as Claude, as it intercepts tool calls and routes them back to Xcode for execution.
|
|
112
155
|
|
|
113
156
|
### Agent skills
|
|
114
157
|
|
|
115
|
-
|
|
158
|
+
[Agent skills](https://docs.github.com/en/copilot/concepts/agents/about-agent-skills) are an open standard for extending AI coding agents with specialised instructions and resources. All three providers support them through the underlying Copilot SDK session, and each agent also has its own skill paths:
|
|
159
|
+
|
|
160
|
+
| Agent | Project skills | Personal skills |
|
|
161
|
+
|---------|--------------------------------------------|------------------------|
|
|
162
|
+
| Copilot | `.github/skills/`, `.claude/skills/` | `~/.copilot/skills/` |
|
|
163
|
+
| Claude | `.claude/skills/` | `~/.claude/skills/` |
|
|
164
|
+
| Codex | `.codex/skills/` | `~/.codex/skills/` |
|
|
116
165
|
|
|
117
166
|
## Configuration
|
|
118
167
|
|
|
@@ -122,7 +171,7 @@ The server reads its configuration from a `config.json5` file. By default, it us
|
|
|
122
171
|
xcode-copilot-server --config ./my-config.json5
|
|
123
172
|
```
|
|
124
173
|
|
|
125
|
-
The config file uses [JSON5](https://json5.org/) format, which supports comments and trailing commas. The `--proxy` flag determines which provider section (`openai` or `
|
|
174
|
+
The config file uses [JSON5](https://json5.org/) format, which supports comments and trailing commas. The `--proxy` flag determines which provider section (`openai`, `claude`, or `codex`) is used at runtime:
|
|
126
175
|
|
|
127
176
|
```json5
|
|
128
177
|
{
|
|
@@ -141,15 +190,23 @@ The config file uses [JSON5](https://json5.org/) format, which supports comments
|
|
|
141
190
|
},
|
|
142
191
|
},
|
|
143
192
|
|
|
144
|
-
|
|
193
|
+
claude: {
|
|
145
194
|
// Intercepts tool calls and forwards them to Xcode so Claude Agent
|
|
146
|
-
//
|
|
195
|
+
// drives tool execution through the IDE instead of the Copilot CLI.
|
|
147
196
|
toolBridge: true,
|
|
148
197
|
|
|
149
198
|
// No MCP servers needed, as Claude Agent handles tools natively.
|
|
150
199
|
mcpServers: {},
|
|
151
200
|
},
|
|
152
201
|
|
|
202
|
+
codex: {
|
|
203
|
+
// Same as Claude: intercepts tool calls and forwards them to Xcode
|
|
204
|
+
// so Codex drives tool execution through the IDE.
|
|
205
|
+
toolBridge: true,
|
|
206
|
+
|
|
207
|
+
mcpServers: {},
|
|
208
|
+
},
|
|
209
|
+
|
|
153
210
|
// Built-in CLI tools allowlist.
|
|
154
211
|
// ["*"] to allow all, [] to deny all, or a list of specific tool names.
|
|
155
212
|
//
|
|
@@ -181,7 +238,7 @@ The config file uses [JSON5](https://json5.org/) format, which supports comments
|
|
|
181
238
|
|
|
182
239
|
This server acts as a local proxy between Xcode and GitHub Copilot. It's designed to run on your machine and isn't intended to be exposed to the internet or shared networks. So, here's what you should know:
|
|
183
240
|
|
|
184
|
-
- The server binds to `127.0.0.1`, so it's only reachable from your machine. Incoming requests are checked for expected user-agent headers (`Xcode/`
|
|
241
|
+
- The server binds to `127.0.0.1`, so it's only reachable from your machine. Incoming requests are checked for expected user-agent headers (`Xcode/` for OpenAI and Codex, `claude-cli/` for Claude), which means casual or accidental connections from other tools will be rejected. This isn't a strong security boundary since user-agent headers can be trivially spoofed, but it helps ensure only the expected client is talking to the server.
|
|
185
242
|
|
|
186
243
|
- The bundled config sets `autoApprovePermissions` to `["read", "mcp"]`, which lets the Copilot session read files and call MCP tools without prompting. Writes, shell commands, and URL fetches are denied by default. You can set it to `true` to approve everything, `false` to deny everything, or pick specific kinds from `"read"`, `"write"`, `"shell"`, `"mcp"`, and `"url"`.
|
|
187
244
|
|
package/config.json5
CHANGED
|
@@ -5,12 +5,11 @@
|
|
|
5
5
|
// exists in both CLI and MCP tools then they can't have different permissions.
|
|
6
6
|
|
|
7
7
|
{
|
|
8
|
-
//
|
|
9
|
-
// section is used at runtime.
|
|
8
|
+
// Which section gets used depends on the --proxy flag.
|
|
10
9
|
|
|
11
10
|
openai: {
|
|
12
11
|
// No tool bridge needed for OpenAI because Xcode drives tool execution
|
|
13
|
-
// directly.
|
|
12
|
+
// directly.
|
|
14
13
|
toolBridge: false,
|
|
15
14
|
|
|
16
15
|
mcpServers: {
|
|
@@ -25,17 +24,23 @@
|
|
|
25
24
|
},
|
|
26
25
|
},
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
// so Claude Agent can drive tool execution through the IDE instead.
|
|
32
|
-
// Set to false or remove to disable the tool bridge.
|
|
27
|
+
claude: {
|
|
28
|
+
// Intercepts tool calls and forwards them to Xcode so Claude Agent
|
|
29
|
+
// drives tool execution through the IDE instead of the Copilot CLI.
|
|
33
30
|
toolBridge: true,
|
|
34
31
|
|
|
35
32
|
// No MCP servers needed, because Claude Agent handles tools natively.
|
|
36
33
|
mcpServers: {},
|
|
37
34
|
},
|
|
38
35
|
|
|
36
|
+
codex: {
|
|
37
|
+
// Same as Claude: intercepts tool calls and forwards them to Xcode
|
|
38
|
+
// so Codex drives tool execution through the IDE.
|
|
39
|
+
toolBridge: true,
|
|
40
|
+
|
|
41
|
+
mcpServers: {},
|
|
42
|
+
},
|
|
43
|
+
|
|
39
44
|
// Built-in Copilot CLI tools allowlist (glob, grep, bash, etc). Use ["*"] to allow
|
|
40
45
|
// all, [] to deny all, or list specific tools like ["glob", "grep"].
|
|
41
46
|
//
|
package/dist/cli-validators.js
CHANGED
|
@@ -28,8 +28,8 @@ export function parseProxy(value) {
|
|
|
28
28
|
return value;
|
|
29
29
|
}
|
|
30
30
|
export function validateAutoPatch(proxy, autoPatch) {
|
|
31
|
-
if (autoPatch && proxy !== "
|
|
32
|
-
throw new Error("--auto-patch can only be used with --proxy
|
|
31
|
+
if (autoPatch && proxy !== "claude" && proxy !== "codex") {
|
|
32
|
+
throw new Error("--auto-patch can only be used with --proxy claude or --proxy codex");
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
//# sourceMappingURL=cli-validators.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-validators.js","sourceRoot":"","sources":["../src/cli-validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAkB,MAAM,sBAAsB,CAAC;AAEjE,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAe,CAAC;AACnE,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAgB,CAAC;AAE5D,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,IAAI,cAAc,CAAC;AACjC,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,KAAK,IAAI,SAAS,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,qBAAqB,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,sBAAsB,KAAK,aAAa,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,kBAAkB,KAAK,aAAa,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAgB,EAAE,SAAkB;IACpE,IAAI,SAAS,IAAI,KAAK,KAAK,
|
|
1
|
+
{"version":3,"file":"cli-validators.js","sourceRoot":"","sources":["../src/cli-validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAkB,MAAM,sBAAsB,CAAC;AAEjE,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAe,CAAC;AACnE,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAgB,CAAC;AAE5D,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,IAAI,cAAc,CAAC;AACjC,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,KAAK,IAAI,SAAS,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,qBAAqB,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,sBAAsB,KAAK,aAAa,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,kBAAkB,KAAK,aAAa,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAgB,EAAE,SAAkB;IACpE,IAAI,SAAS,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;AACH,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { ProxyName } from "./providers/index.js";
|
|
|
3
3
|
import { type MCPServer, type RawServerConfig } from "./schemas/config.js";
|
|
4
4
|
export type { MCPLocalServer, MCPRemoteServer, MCPServer, ApprovalRule, ReasoningEffort, } from "./schemas/config.js";
|
|
5
5
|
export type { ProxyName };
|
|
6
|
-
export type ServerConfig = Omit<RawServerConfig, "bodyLimitMiB" | "openai" | "
|
|
6
|
+
export type ServerConfig = Omit<RawServerConfig, "bodyLimitMiB" | "openai" | "claude" | "codex"> & {
|
|
7
7
|
toolBridge: boolean;
|
|
8
8
|
mcpServers: Record<string, MCPServer>;
|
|
9
9
|
bodyLimit: number;
|
package/dist/config.js
CHANGED
|
@@ -8,7 +8,7 @@ const DEFAULT_CONFIG = {
|
|
|
8
8
|
mcpServers: {},
|
|
9
9
|
allowedCliTools: [],
|
|
10
10
|
excludedFilePatterns: [],
|
|
11
|
-
bodyLimit: 10 * 1024 * 1024,
|
|
11
|
+
bodyLimit: 10 * 1024 * 1024,
|
|
12
12
|
autoApprovePermissions: ["read", "mcp"],
|
|
13
13
|
};
|
|
14
14
|
function resolveServerPaths(servers, configDir) {
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EACL,kBAAkB,GAGnB,MAAM,qBAAqB,CAAC;AAiB7B,MAAM,cAAc,GAAG;IACrB,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE,EAAE;IACd,eAAe,EAAE,EAAE;IACnB,oBAAoB,EAAE,EAAE;IACxB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CopilotSession } from "@github/copilot-sdk";
|
|
2
2
|
import { ToolBridgeState } from "./tool-bridge/state.js";
|
|
3
|
-
import type { AnthropicMessage } from "./schemas
|
|
3
|
+
import type { AnthropicMessage } from "./providers/claude/schemas.js";
|
|
4
4
|
import type { Logger } from "./logger.js";
|
|
5
5
|
export interface Conversation {
|
|
6
6
|
id: string;
|
|
@@ -25,6 +25,7 @@ export declare class ConversationManager {
|
|
|
25
25
|
isReuse: boolean;
|
|
26
26
|
};
|
|
27
27
|
findByContinuation(messages: AnthropicMessage[]): Conversation | undefined;
|
|
28
|
+
findByContinuationIds(callIds: string[]): Conversation | undefined;
|
|
28
29
|
findByExpectedTool(name: string): ToolBridgeState | undefined;
|
|
29
30
|
getState(convId: string): ToolBridgeState | undefined;
|
|
30
31
|
remove(convId: string): void;
|
|
@@ -81,7 +81,7 @@ export class ConversationManager {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
//
|
|
84
|
+
// The model sometimes retries a tool after an internal failure so the
|
|
85
85
|
// tool_use_id won't match anything, but we can still route by session
|
|
86
86
|
for (const [, conv] of this.conversations) {
|
|
87
87
|
if (conv.state.sessionActive) {
|
|
@@ -91,6 +91,25 @@ export class ConversationManager {
|
|
|
91
91
|
}
|
|
92
92
|
return undefined;
|
|
93
93
|
}
|
|
94
|
+
findByContinuationIds(callIds) {
|
|
95
|
+
if (callIds.length === 0)
|
|
96
|
+
return undefined;
|
|
97
|
+
for (const [, conv] of this.conversations) {
|
|
98
|
+
for (const callId of callIds) {
|
|
99
|
+
if (conv.state.hasPendingToolCall(callId)) {
|
|
100
|
+
this.logger.debug(`Continuation matched conversation ${conv.id} via call_id ${callId}`);
|
|
101
|
+
return conv;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
for (const [, conv] of this.conversations) {
|
|
106
|
+
if (conv.state.sessionActive) {
|
|
107
|
+
this.logger.debug(`Continuation matched conversation ${conv.id} via sessionActive fallback`);
|
|
108
|
+
return conv;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
94
113
|
findByExpectedTool(name) {
|
|
95
114
|
for (const [, conv] of this.conversations) {
|
|
96
115
|
if (conv.state.hasExpectedTool(name)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-manager.js","sourceRoot":"","sources":["../src/conversation-manager.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"conversation-manager.js","sourceRoot":"","sources":["../src/conversation-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FastifyReply } from "fastify";
|
|
2
|
+
import type { CopilotSession } from "@github/copilot-sdk";
|
|
3
|
+
import type { Logger } from "../../logger.js";
|
|
4
|
+
import type { ToolBridgeState } from "../../tool-bridge/state.js";
|
|
5
|
+
export declare function startResponseStream(reply: FastifyReply, responseId: string, model: string): void;
|
|
6
|
+
export declare function handleResponsesStreaming(state: ToolBridgeState, session: CopilotSession, prompt: string, model: string, logger: Logger, hasBridge: boolean, responseId: string): Promise<void>;
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { currentTimestamp, genId } from "../../schemas/responses.js";
|
|
2
|
+
import { formatCompaction, SSE_HEADERS, sendSSEEvent as sendEvent, sendSSEComment } from "../streaming-utils.js";
|
|
3
|
+
const MCP_PREFIX = "xcode-bridge-";
|
|
4
|
+
export function startResponseStream(reply, responseId, model) {
|
|
5
|
+
reply.raw.writeHead(200, SSE_HEADERS);
|
|
6
|
+
const response = {
|
|
7
|
+
id: responseId,
|
|
8
|
+
object: "response",
|
|
9
|
+
created_at: currentTimestamp(),
|
|
10
|
+
model,
|
|
11
|
+
status: "in_progress",
|
|
12
|
+
output: [],
|
|
13
|
+
};
|
|
14
|
+
sendEvent(reply, "response.created", { response });
|
|
15
|
+
sendEvent(reply, "response.in_progress", { response });
|
|
16
|
+
}
|
|
17
|
+
export async function handleResponsesStreaming(state, session, prompt, model, logger, hasBridge, responseId) {
|
|
18
|
+
const reply = state.currentReply;
|
|
19
|
+
if (!reply)
|
|
20
|
+
throw new Error("No reply set on bridge state");
|
|
21
|
+
startResponseStream(reply, responseId, model);
|
|
22
|
+
state.markSessionActive();
|
|
23
|
+
let pendingDeltas = [];
|
|
24
|
+
let sessionDone = false;
|
|
25
|
+
// Send keepalive comments every 15s to prevent client timeouts
|
|
26
|
+
// during long internal tool execution periods.
|
|
27
|
+
const keepaliveInterval = setInterval(() => {
|
|
28
|
+
const r = state.currentReply;
|
|
29
|
+
if (r)
|
|
30
|
+
sendSSEComment(r);
|
|
31
|
+
}, 15_000);
|
|
32
|
+
// lazily created on first text delta
|
|
33
|
+
let messageItem = null;
|
|
34
|
+
let messageStarted = false;
|
|
35
|
+
let outputIndex = 0;
|
|
36
|
+
const outputItems = [];
|
|
37
|
+
const accumulatedText = [];
|
|
38
|
+
const toolNames = new Map();
|
|
39
|
+
function getReply() {
|
|
40
|
+
return state.currentReply;
|
|
41
|
+
}
|
|
42
|
+
function ensureMessageItem(r) {
|
|
43
|
+
if (!messageStarted) {
|
|
44
|
+
messageItem = {
|
|
45
|
+
type: "message",
|
|
46
|
+
id: genId("msg"),
|
|
47
|
+
status: "in_progress",
|
|
48
|
+
role: "assistant",
|
|
49
|
+
content: [],
|
|
50
|
+
};
|
|
51
|
+
sendEvent(r, "response.output_item.added", {
|
|
52
|
+
output_index: outputIndex,
|
|
53
|
+
item: messageItem,
|
|
54
|
+
});
|
|
55
|
+
sendEvent(r, "response.content_part.added", {
|
|
56
|
+
item_id: messageItem.id,
|
|
57
|
+
output_index: outputIndex,
|
|
58
|
+
content_index: 0,
|
|
59
|
+
part: { type: "output_text", text: "", annotations: [] },
|
|
60
|
+
});
|
|
61
|
+
messageStarted = true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function flushPending() {
|
|
65
|
+
const r = getReply();
|
|
66
|
+
if (!r || pendingDeltas.length === 0)
|
|
67
|
+
return;
|
|
68
|
+
ensureMessageItem(r);
|
|
69
|
+
for (const text of pendingDeltas) {
|
|
70
|
+
sendEvent(r, "response.output_text.delta", {
|
|
71
|
+
item_id: messageItem.id,
|
|
72
|
+
output_index: outputIndex,
|
|
73
|
+
content_index: 0,
|
|
74
|
+
delta: text,
|
|
75
|
+
});
|
|
76
|
+
accumulatedText.push(text);
|
|
77
|
+
}
|
|
78
|
+
pendingDeltas = [];
|
|
79
|
+
}
|
|
80
|
+
function closeMessageItem(r) {
|
|
81
|
+
if (!messageStarted || !messageItem)
|
|
82
|
+
return;
|
|
83
|
+
const fullText = accumulatedText.join("");
|
|
84
|
+
sendEvent(r, "response.output_text.done", {
|
|
85
|
+
item_id: messageItem.id,
|
|
86
|
+
output_index: outputIndex,
|
|
87
|
+
content_index: 0,
|
|
88
|
+
text: fullText,
|
|
89
|
+
});
|
|
90
|
+
sendEvent(r, "response.content_part.done", {
|
|
91
|
+
item_id: messageItem.id,
|
|
92
|
+
output_index: outputIndex,
|
|
93
|
+
content_index: 0,
|
|
94
|
+
part: { type: "output_text", text: fullText, annotations: [] },
|
|
95
|
+
});
|
|
96
|
+
messageItem.status = "completed";
|
|
97
|
+
messageItem.content = [{ type: "output_text", text: fullText, annotations: [] }];
|
|
98
|
+
outputItems.push(messageItem);
|
|
99
|
+
sendEvent(r, "response.output_item.done", {
|
|
100
|
+
output_index: outputIndex,
|
|
101
|
+
item: messageItem,
|
|
102
|
+
});
|
|
103
|
+
outputIndex++;
|
|
104
|
+
messageStarted = false;
|
|
105
|
+
messageItem = null;
|
|
106
|
+
}
|
|
107
|
+
function finishReply(r, status) {
|
|
108
|
+
clearInterval(keepaliveInterval);
|
|
109
|
+
const response = {
|
|
110
|
+
id: responseId,
|
|
111
|
+
object: "response",
|
|
112
|
+
created_at: currentTimestamp(),
|
|
113
|
+
model,
|
|
114
|
+
status,
|
|
115
|
+
output: outputItems,
|
|
116
|
+
};
|
|
117
|
+
sendEvent(r, `response.${status}`, { response });
|
|
118
|
+
r.raw.end();
|
|
119
|
+
state.clearReply();
|
|
120
|
+
state.notifyStreamingDone();
|
|
121
|
+
// reset for potential continuation
|
|
122
|
+
messageStarted = false;
|
|
123
|
+
messageItem = null;
|
|
124
|
+
outputIndex = 0;
|
|
125
|
+
outputItems.length = 0;
|
|
126
|
+
accumulatedText.length = 0;
|
|
127
|
+
}
|
|
128
|
+
const unsubscribe = session.on((event) => {
|
|
129
|
+
logger.debug(`Session event: ${event.type}`);
|
|
130
|
+
if (event.type === "tool.execution_start") {
|
|
131
|
+
const d = event.data;
|
|
132
|
+
toolNames.set(d.toolCallId, d.toolName);
|
|
133
|
+
logger.debug(`Running ${d.toolName} (id=${d.toolCallId}, args=${JSON.stringify(d.arguments)})`);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (event.type === "tool.execution_complete") {
|
|
137
|
+
const d = event.data;
|
|
138
|
+
const name = toolNames.get(d.toolCallId) ?? d.toolCallId;
|
|
139
|
+
toolNames.delete(d.toolCallId);
|
|
140
|
+
const detail = d.success
|
|
141
|
+
? JSON.stringify(d.result?.content)
|
|
142
|
+
: d.error?.message ?? "failed";
|
|
143
|
+
logger.debug(`${name} done (success=${String(d.success)}, ${detail})`);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
switch (event.type) {
|
|
147
|
+
case "assistant.message_delta":
|
|
148
|
+
if (event.data.deltaContent) {
|
|
149
|
+
logger.debug(`Delta: ${event.data.deltaContent}`);
|
|
150
|
+
pendingDeltas.push(event.data.deltaContent);
|
|
151
|
+
}
|
|
152
|
+
break;
|
|
153
|
+
case "assistant.message": {
|
|
154
|
+
logger.debug(`assistant.message: toolRequests=${String(event.data.toolRequests?.length ?? 0)}`);
|
|
155
|
+
if (event.data.toolRequests && event.data.toolRequests.length > 0) {
|
|
156
|
+
const bridgeRequests = hasBridge
|
|
157
|
+
? event.data.toolRequests.filter((tr) => tr.name.startsWith(MCP_PREFIX))
|
|
158
|
+
: event.data.toolRequests;
|
|
159
|
+
if (hasBridge && bridgeRequests.length < event.data.toolRequests.length) {
|
|
160
|
+
const skipped = event.data.toolRequests.length - bridgeRequests.length;
|
|
161
|
+
logger.debug(`Skipped ${String(skipped)} non-bridge tool request(s)`);
|
|
162
|
+
}
|
|
163
|
+
if (bridgeRequests.length > 0) {
|
|
164
|
+
// Xcode's Codex client does not process function_call items
|
|
165
|
+
// (it won't send function_call_output back), so emitting them
|
|
166
|
+
// breaks the conversation protocol. Instead we let the SDK
|
|
167
|
+
// handle bridge tools via MCP internally. The MCP tools/call
|
|
168
|
+
// will fail fast (no expected entry registered), prompting the
|
|
169
|
+
// model to fall back to its built-in tools.
|
|
170
|
+
const names = bridgeRequests.map((tr) => tr.name).join(", ");
|
|
171
|
+
logger.debug(`Bridge tool(s) requested (${names}), handled via MCP internally`);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
logger.debug("All tool requests were non-bridge, none emitted");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
const r = getReply();
|
|
179
|
+
if (r) {
|
|
180
|
+
logger.debug(`Flushing ${String(pendingDeltas.length)} pending deltas`);
|
|
181
|
+
flushPending();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
case "session.idle": {
|
|
187
|
+
logger.info(`Done, wrapping up stream (pendingDeltas=${String(pendingDeltas.length)})`);
|
|
188
|
+
sessionDone = true;
|
|
189
|
+
state.markSessionInactive();
|
|
190
|
+
flushPending();
|
|
191
|
+
const r = getReply();
|
|
192
|
+
if (r) {
|
|
193
|
+
if (!messageStarted) {
|
|
194
|
+
ensureMessageItem(r);
|
|
195
|
+
}
|
|
196
|
+
closeMessageItem(r);
|
|
197
|
+
finishReply(r, "completed");
|
|
198
|
+
}
|
|
199
|
+
unsubscribe();
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
case "session.compaction_start":
|
|
203
|
+
logger.info("Compacting context...");
|
|
204
|
+
break;
|
|
205
|
+
case "session.compaction_complete":
|
|
206
|
+
logger.info(`Context compacted: ${formatCompaction(event.data)}`);
|
|
207
|
+
break;
|
|
208
|
+
case "session.error": {
|
|
209
|
+
logger.error(`Session error: ${event.data.message}`);
|
|
210
|
+
sessionDone = true;
|
|
211
|
+
state.markSessionErrored();
|
|
212
|
+
state.markSessionInactive();
|
|
213
|
+
const r = getReply();
|
|
214
|
+
if (r) {
|
|
215
|
+
if (messageStarted) {
|
|
216
|
+
closeMessageItem(r);
|
|
217
|
+
}
|
|
218
|
+
finishReply(r, "failed");
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
// finishReply not called, so notify manually
|
|
222
|
+
clearInterval(keepaliveInterval);
|
|
223
|
+
state.notifyStreamingDone();
|
|
224
|
+
}
|
|
225
|
+
unsubscribe();
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
default:
|
|
229
|
+
logger.debug(`Unhandled event: ${event.type}, data=${JSON.stringify(event.data)}`);
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
reply.raw.on("close", () => {
|
|
234
|
+
if (!sessionDone && state.currentReply === reply) {
|
|
235
|
+
logger.info("Client disconnected, aborting session");
|
|
236
|
+
clearInterval(keepaliveInterval);
|
|
237
|
+
messageStarted = false;
|
|
238
|
+
messageItem = null;
|
|
239
|
+
state.markSessionErrored();
|
|
240
|
+
state.cleanup();
|
|
241
|
+
unsubscribe();
|
|
242
|
+
session.abort().catch((err) => {
|
|
243
|
+
logger.error("Failed to abort session:", err);
|
|
244
|
+
});
|
|
245
|
+
state.notifyStreamingDone();
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
const done = state.waitForStreamingDone();
|
|
249
|
+
session.send({ prompt }).catch((err) => {
|
|
250
|
+
logger.error("Failed to send prompt:", err);
|
|
251
|
+
clearInterval(keepaliveInterval);
|
|
252
|
+
sessionDone = true;
|
|
253
|
+
messageStarted = false;
|
|
254
|
+
messageItem = null;
|
|
255
|
+
const r = getReply();
|
|
256
|
+
if (r) {
|
|
257
|
+
r.raw.end();
|
|
258
|
+
state.clearReply();
|
|
259
|
+
}
|
|
260
|
+
unsubscribe();
|
|
261
|
+
state.notifyStreamingDone();
|
|
262
|
+
});
|
|
263
|
+
return done;
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=streaming.js.map
|