pi-commandcode-provider 0.5.1 → 0.6.1
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/CHANGELOG.md +54 -0
- package/CONTRIBUTING.md +10 -0
- package/README.md +41 -13
- package/index.ts +106 -38
- package/package.json +13 -4
- package/scripts/live-e2e-profile.mjs +87 -0
- package/scripts/pi-authenticated.mjs +1 -0
- package/scripts/pi-isolated.mjs +1 -0
- package/src/api-key.ts +69 -0
- package/src/auth-server.ts +7 -0
- package/src/commandcode-catalog-overrides.ts +23 -0
- package/src/commandcode-catalog.ts +152 -0
- package/src/converters.ts +78 -17
- package/src/core.ts +117 -23
- package/src/models.ts +68 -97
- package/src/oauth.ts +84 -22
- package/src/pricing.ts +58 -53
- package/src/quota-command.ts +66 -0
- package/src/quota-format.ts +143 -0
- package/src/quota-types.ts +47 -0
- package/src/quota.ts +342 -0
- package/src/runtime.ts +49 -8
- package/src/transport.ts +140 -0
- package/src/types.ts +9 -0
package/src/transport.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AssistantMessageEvent,
|
|
3
|
+
AssistantMessageEventStreamLike,
|
|
4
|
+
ContextLike,
|
|
5
|
+
ModelLike,
|
|
6
|
+
StreamOptions,
|
|
7
|
+
} from "./types.ts"
|
|
8
|
+
|
|
9
|
+
export type CommandCodeTransport = "unknown" | "provider" | "generate"
|
|
10
|
+
|
|
11
|
+
interface TransportDependencies {
|
|
12
|
+
createStream: () => AssistantMessageEventStreamLike
|
|
13
|
+
streamProvider: (
|
|
14
|
+
model: ModelLike,
|
|
15
|
+
context: ContextLike,
|
|
16
|
+
options?: StreamOptions,
|
|
17
|
+
) => AssistantMessageEventStreamLike
|
|
18
|
+
streamGenerate: (
|
|
19
|
+
model: ModelLike,
|
|
20
|
+
context: ContextLike,
|
|
21
|
+
options?: StreamOptions,
|
|
22
|
+
) => AssistantMessageEventStreamLike
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
26
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function isUpgradeRequired(response: Response): Promise<boolean> {
|
|
30
|
+
if (response.status !== 403) return false
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const body: unknown = await response.clone().json()
|
|
34
|
+
if (!isRecord(body)) return false
|
|
35
|
+
const error = isRecord(body.error) ? body.error : body
|
|
36
|
+
return error.code === "upgrade_required"
|
|
37
|
+
} catch {
|
|
38
|
+
return false
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function createCommandCodeTransportRouter(deps: TransportDependencies) {
|
|
43
|
+
let transport: CommandCodeTransport = "unknown"
|
|
44
|
+
let apiKey: string | undefined
|
|
45
|
+
|
|
46
|
+
function pipe(
|
|
47
|
+
source: AssistantMessageEventStreamLike,
|
|
48
|
+
target: AssistantMessageEventStreamLike,
|
|
49
|
+
): Promise<void> {
|
|
50
|
+
return (async () => {
|
|
51
|
+
for await (const event of source) target.push(event)
|
|
52
|
+
})()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
getTransport(): CommandCodeTransport {
|
|
57
|
+
return transport
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
reset(): void {
|
|
61
|
+
transport = "unknown"
|
|
62
|
+
apiKey = undefined
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
stream(
|
|
66
|
+
model: ModelLike,
|
|
67
|
+
context: ContextLike,
|
|
68
|
+
options?: StreamOptions,
|
|
69
|
+
): AssistantMessageEventStreamLike {
|
|
70
|
+
if (options?.apiKey !== apiKey) {
|
|
71
|
+
apiKey = options?.apiKey
|
|
72
|
+
transport = "unknown"
|
|
73
|
+
}
|
|
74
|
+
const requestApiKey = options?.apiKey
|
|
75
|
+
if (transport === "generate") return deps.streamGenerate(model, context, options)
|
|
76
|
+
|
|
77
|
+
const output = deps.createStream()
|
|
78
|
+
let upgradeRequired = false
|
|
79
|
+
const fetchImpl = options?.fetch ?? fetch
|
|
80
|
+
const providerOptions: StreamOptions = {
|
|
81
|
+
...options,
|
|
82
|
+
fetch: async (input, init) => {
|
|
83
|
+
const response = await fetchImpl(input, init)
|
|
84
|
+
if (await isUpgradeRequired(response)) upgradeRequired = true
|
|
85
|
+
return response
|
|
86
|
+
},
|
|
87
|
+
onResponse: async (response, responseModel) => {
|
|
88
|
+
if (upgradeRequired) return
|
|
89
|
+
await options?.onResponse?.(response, responseModel)
|
|
90
|
+
},
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const run = async () => {
|
|
94
|
+
const providerStream = deps.streamProvider(model, context, providerOptions)
|
|
95
|
+
|
|
96
|
+
for await (const event of providerStream) {
|
|
97
|
+
if (!upgradeRequired) {
|
|
98
|
+
if (apiKey === requestApiKey) transport = "provider"
|
|
99
|
+
output.push(event)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (upgradeRequired) {
|
|
104
|
+
if (apiKey === requestApiKey) transport = "generate"
|
|
105
|
+
await pipe(deps.streamGenerate(model, context, options), output)
|
|
106
|
+
}
|
|
107
|
+
output.end()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
run().catch((error: unknown) => {
|
|
111
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
112
|
+
output.push({
|
|
113
|
+
type: "error",
|
|
114
|
+
reason: "error",
|
|
115
|
+
error: {
|
|
116
|
+
role: "assistant",
|
|
117
|
+
content: [],
|
|
118
|
+
api: model.api,
|
|
119
|
+
provider: model.provider,
|
|
120
|
+
model: model.id,
|
|
121
|
+
usage: {
|
|
122
|
+
input: 0,
|
|
123
|
+
output: 0,
|
|
124
|
+
cacheRead: 0,
|
|
125
|
+
cacheWrite: 0,
|
|
126
|
+
totalTokens: 0,
|
|
127
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
128
|
+
},
|
|
129
|
+
stopReason: "error",
|
|
130
|
+
errorMessage: message,
|
|
131
|
+
timestamp: Date.now(),
|
|
132
|
+
},
|
|
133
|
+
})
|
|
134
|
+
output.end()
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
return output
|
|
138
|
+
},
|
|
139
|
+
}
|
|
140
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -110,7 +110,10 @@ export interface StreamOptions {
|
|
|
110
110
|
apiKey?: string
|
|
111
111
|
signal?: AbortSignal
|
|
112
112
|
headers?: Record<string, string>
|
|
113
|
+
fetch?: typeof fetch
|
|
113
114
|
maxTokens?: number
|
|
115
|
+
temperature?: number
|
|
116
|
+
sessionId?: string
|
|
114
117
|
/** Resolved pi thinking level; forwarded only through the model's map. */
|
|
115
118
|
reasoning?: string
|
|
116
119
|
onPayload?: (payload: unknown, model: ModelLike) => unknown | Promise<unknown>
|
|
@@ -171,6 +174,12 @@ export type AssistantMessageEvent =
|
|
|
171
174
|
contentIndex: number
|
|
172
175
|
partial: AssistantMessageLike
|
|
173
176
|
}
|
|
177
|
+
| {
|
|
178
|
+
type: "toolcall_delta"
|
|
179
|
+
contentIndex: number
|
|
180
|
+
delta: string
|
|
181
|
+
partial: AssistantMessageLike
|
|
182
|
+
}
|
|
174
183
|
| {
|
|
175
184
|
type: "toolcall_end"
|
|
176
185
|
contentIndex: number
|