@x-otto/plugin-github-copilot 0.1.0-alpha.4 → 0.1.0-alpha.9
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/package.json +8 -4
- package/plugin-dist/meta.json +1 -1
- package/plugin-dist/plugin.cjs +355 -26417
- package/src/provider.test.ts +19 -0
- package/src/provider.ts +9 -6
package/src/provider.test.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
inferCopilotInitiator,
|
|
6
6
|
hasCopilotVisionInput,
|
|
7
7
|
buildCopilotDynamicHeaders,
|
|
8
|
+
buildCopilotHeaders,
|
|
8
9
|
} from './provider'
|
|
9
10
|
|
|
10
11
|
import type {
|
|
@@ -152,6 +153,24 @@ describe('hasCopilotVisionInput', () => {
|
|
|
152
153
|
})
|
|
153
154
|
})
|
|
154
155
|
|
|
156
|
+
describe('buildCopilotHeaders + dynamic 合并:openai-intent 无同名异 case 冲突(findings-backlog B2)', () => {
|
|
157
|
+
it('#then 静态 headers 不含 openai-intent(由 dynamic 单一真源提供)', () => {
|
|
158
|
+
const staticHeaders = buildCopilotHeaders('tok')
|
|
159
|
+
const keys = Object.keys(staticHeaders).map((k) => k.toLowerCase())
|
|
160
|
+
expect(keys).not.toContain('openai-intent')
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
it('#then 合并后(static ∪ dynamic)openai-intent 大小写不敏感恰一处,值为 dynamic 的 conversation-edits', () => {
|
|
164
|
+
const merged = {
|
|
165
|
+
...buildCopilotHeaders('tok'),
|
|
166
|
+
...buildCopilotDynamicHeaders({ messages: [makeUserMessage('hi')], hasImages: false }),
|
|
167
|
+
}
|
|
168
|
+
const intentKeys = Object.keys(merged).filter((k) => k.toLowerCase() === 'openai-intent')
|
|
169
|
+
expect(intentKeys).toHaveLength(1) // 此前静态 'openai-intent' + 动态 'Openai-Intent' 共存 = 2,会被服务端视为 header 重复
|
|
170
|
+
expect(merged[intentKeys[0]!]).toBe('conversation-edits')
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
|
|
155
174
|
describe('buildCopilotDynamicHeaders', () => {
|
|
156
175
|
it('sets X-Initiator and Openai-Intent', () => {
|
|
157
176
|
const messages: Message[] = [makeUserMessage('hello')]
|
package/src/provider.ts
CHANGED
|
@@ -25,15 +25,13 @@ import {
|
|
|
25
25
|
type StreamOptions,
|
|
26
26
|
type ProviderStream,
|
|
27
27
|
type WireProtocolLogger,
|
|
28
|
+
noopWireProtocolLogger,
|
|
28
29
|
} from '@x-otto/provider'
|
|
29
30
|
|
|
30
|
-
/** RFC-185 D3:日志走宿主注入端口,缺省 no-op——插件源码禁 createLogger(防第二单例直写 stderr)。 */
|
|
31
|
-
const noopLogger: WireProtocolLogger = { debug: () => {}, info: () => {}, warn: () => {}, error: () => {} }
|
|
32
|
-
|
|
33
31
|
const PROVIDER_VERSION = '1.0.0'
|
|
34
32
|
const DEFAULT_COPILOT_INTEGRATION_ID = 'vscode-chat'
|
|
35
33
|
|
|
36
|
-
function buildCopilotHeaders(token: string): Record<string, string> {
|
|
34
|
+
export function buildCopilotHeaders(token: string): Record<string, string> {
|
|
37
35
|
const integrationId = process.env['OTTO_COPILOT_INTEGRATION_ID'] || DEFAULT_COPILOT_INTEGRATION_ID
|
|
38
36
|
|
|
39
37
|
return {
|
|
@@ -41,7 +39,12 @@ function buildCopilotHeaders(token: string): Record<string, string> {
|
|
|
41
39
|
'copilot-integration-id': integrationId,
|
|
42
40
|
'editor-version': `otto-coding/${PROVIDER_VERSION}`,
|
|
43
41
|
'editor-plugin-version': `otto-coding/${PROVIDER_VERSION}`,
|
|
44
|
-
|
|
42
|
+
// 注意:openai-intent **不在此处设**——它由 buildCopilotDynamicHeaders 的
|
|
43
|
+
// `Openai-Intent` 单一真源提供(值随发起方 initiator 变化)。此前这里静态设
|
|
44
|
+
// `'openai-intent': 'conversation-panel'` 与动态的 `'Openai-Intent': 'conversation-edits'`
|
|
45
|
+
// 同名异 case 共存:JS object 是两个 key、HTTP header 名却大小写不敏感,合并后同一
|
|
46
|
+
// header 出现两次、取值歧义(服务端行为未定义)。删静态项,动态项恒设(两者都无条件
|
|
47
|
+
// spread,见 converse),故无覆盖缺口。
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
50
|
|
|
@@ -89,7 +92,7 @@ class GitHubCopilotStream implements ProviderStream {
|
|
|
89
92
|
|
|
90
93
|
constructor(
|
|
91
94
|
private readonly resolveOAuthAccessKey?: CopilotCredentialResolver,
|
|
92
|
-
private readonly logger: WireProtocolLogger =
|
|
95
|
+
private readonly logger: WireProtocolLogger = noopWireProtocolLogger,
|
|
93
96
|
) {}
|
|
94
97
|
|
|
95
98
|
/** 统一鉴权解析(RFC-140 D5,`ProviderStream.resolveAuth`)——Copilot 用户令牌走 oauth 模式。 */
|