@link-assistant/agent 0.0.8 → 0.0.11
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/EXAMPLES.md +80 -1
- package/MODELS.md +72 -24
- package/README.md +95 -2
- package/TOOLS.md +20 -0
- package/package.json +36 -2
- package/src/agent/agent.ts +68 -54
- package/src/auth/claude-oauth.ts +426 -0
- package/src/auth/index.ts +28 -26
- package/src/auth/plugins.ts +876 -0
- package/src/bun/index.ts +53 -43
- package/src/bus/global.ts +5 -5
- package/src/bus/index.ts +59 -53
- package/src/cli/bootstrap.js +12 -12
- package/src/cli/bootstrap.ts +6 -6
- package/src/cli/cmd/agent.ts +97 -92
- package/src/cli/cmd/auth.ts +468 -0
- package/src/cli/cmd/cmd.ts +2 -2
- package/src/cli/cmd/export.ts +41 -41
- package/src/cli/cmd/mcp.ts +210 -53
- package/src/cli/cmd/models.ts +30 -29
- package/src/cli/cmd/run.ts +269 -213
- package/src/cli/cmd/stats.ts +185 -146
- package/src/cli/error.ts +17 -13
- package/src/cli/ui.ts +78 -0
- package/src/command/index.ts +26 -26
- package/src/config/config.ts +528 -288
- package/src/config/markdown.ts +15 -15
- package/src/file/ripgrep.ts +201 -169
- package/src/file/time.ts +21 -18
- package/src/file/watcher.ts +51 -42
- package/src/file.ts +1 -1
- package/src/flag/flag.ts +26 -11
- package/src/format/formatter.ts +206 -162
- package/src/format/index.ts +61 -61
- package/src/global/index.ts +21 -21
- package/src/id/id.ts +47 -33
- package/src/index.js +554 -332
- package/src/json-standard/index.ts +173 -0
- package/src/mcp/index.ts +135 -128
- package/src/patch/index.ts +336 -267
- package/src/project/bootstrap.ts +15 -15
- package/src/project/instance.ts +43 -36
- package/src/project/project.ts +47 -47
- package/src/project/state.ts +37 -33
- package/src/provider/models-macro.ts +5 -5
- package/src/provider/models.ts +32 -32
- package/src/provider/opencode.js +19 -19
- package/src/provider/provider.ts +518 -277
- package/src/provider/transform.ts +143 -102
- package/src/server/project.ts +21 -21
- package/src/server/server.ts +111 -105
- package/src/session/agent.js +66 -60
- package/src/session/compaction.ts +136 -111
- package/src/session/index.ts +189 -156
- package/src/session/message-v2.ts +312 -268
- package/src/session/message.ts +73 -57
- package/src/session/processor.ts +180 -166
- package/src/session/prompt.ts +678 -533
- package/src/session/retry.ts +26 -23
- package/src/session/revert.ts +76 -62
- package/src/session/status.ts +26 -26
- package/src/session/summary.ts +97 -76
- package/src/session/system.ts +77 -63
- package/src/session/todo.ts +22 -16
- package/src/snapshot/index.ts +92 -76
- package/src/storage/storage.ts +157 -120
- package/src/tool/bash.ts +116 -106
- package/src/tool/batch.ts +73 -59
- package/src/tool/codesearch.ts +60 -53
- package/src/tool/edit.ts +319 -263
- package/src/tool/glob.ts +32 -28
- package/src/tool/grep.ts +72 -53
- package/src/tool/invalid.ts +7 -7
- package/src/tool/ls.ts +77 -64
- package/src/tool/multiedit.ts +30 -21
- package/src/tool/patch.ts +121 -94
- package/src/tool/read.ts +140 -122
- package/src/tool/registry.ts +38 -38
- package/src/tool/task.ts +93 -60
- package/src/tool/todo.ts +16 -16
- package/src/tool/tool.ts +45 -36
- package/src/tool/webfetch.ts +97 -74
- package/src/tool/websearch.ts +78 -64
- package/src/tool/write.ts +21 -15
- package/src/util/binary.ts +27 -19
- package/src/util/context.ts +8 -8
- package/src/util/defer.ts +7 -5
- package/src/util/error.ts +24 -19
- package/src/util/eventloop.ts +16 -10
- package/src/util/filesystem.ts +37 -33
- package/src/util/fn.ts +11 -8
- package/src/util/iife.ts +1 -1
- package/src/util/keybind.ts +44 -44
- package/src/util/lazy.ts +7 -7
- package/src/util/locale.ts +20 -16
- package/src/util/lock.ts +43 -38
- package/src/util/log.ts +95 -85
- package/src/util/queue.ts +8 -8
- package/src/util/rpc.ts +35 -23
- package/src/util/scrap.ts +4 -4
- package/src/util/signal.ts +5 -5
- package/src/util/timeout.ts +6 -6
- package/src/util/token.ts +2 -2
- package/src/util/wildcard.ts +38 -27
package/src/session/index.ts
CHANGED
|
@@ -1,42 +1,45 @@
|
|
|
1
|
-
import { Decimal } from
|
|
2
|
-
import z from
|
|
3
|
-
import { type LanguageModelUsage, type ProviderMetadata } from
|
|
4
|
-
import { Bus } from
|
|
5
|
-
import { Config } from
|
|
6
|
-
import { Flag } from
|
|
7
|
-
import { Identifier } from
|
|
8
|
-
import type { ModelsDev } from
|
|
9
|
-
import { Storage } from
|
|
10
|
-
import { Log } from
|
|
11
|
-
import { MessageV2 } from
|
|
12
|
-
import { Instance } from
|
|
13
|
-
import { SessionPrompt } from
|
|
14
|
-
import { fn } from
|
|
15
|
-
import { Command } from
|
|
16
|
-
import { Snapshot } from
|
|
1
|
+
import { Decimal } from 'decimal.js';
|
|
2
|
+
import z from 'zod';
|
|
3
|
+
import { type LanguageModelUsage, type ProviderMetadata } from 'ai';
|
|
4
|
+
import { Bus } from '../bus';
|
|
5
|
+
import { Config } from '../config/config';
|
|
6
|
+
import { Flag } from '../flag/flag';
|
|
7
|
+
import { Identifier } from '../id/id';
|
|
8
|
+
import type { ModelsDev } from '../provider/models';
|
|
9
|
+
import { Storage } from '../storage/storage';
|
|
10
|
+
import { Log } from '../util/log';
|
|
11
|
+
import { MessageV2 } from './message-v2';
|
|
12
|
+
import { Instance } from '../project/instance';
|
|
13
|
+
import { SessionPrompt } from './prompt';
|
|
14
|
+
import { fn } from '../util/fn';
|
|
15
|
+
import { Command } from '../command';
|
|
16
|
+
import { Snapshot } from '../snapshot';
|
|
17
17
|
|
|
18
18
|
export namespace Session {
|
|
19
|
-
const log = Log.create({ service:
|
|
19
|
+
const log = Log.create({ service: 'session' });
|
|
20
20
|
|
|
21
|
-
const parentTitlePrefix =
|
|
22
|
-
const childTitlePrefix =
|
|
21
|
+
const parentTitlePrefix = 'New session - ';
|
|
22
|
+
const childTitlePrefix = 'Child session - ';
|
|
23
23
|
|
|
24
24
|
function createDefaultTitle(isChild = false) {
|
|
25
|
-
return (
|
|
25
|
+
return (
|
|
26
|
+
(isChild ? childTitlePrefix : parentTitlePrefix) +
|
|
27
|
+
new Date().toISOString()
|
|
28
|
+
);
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
export function isDefaultTitle(title: string) {
|
|
29
32
|
return new RegExp(
|
|
30
|
-
`^(${parentTitlePrefix}|${childTitlePrefix})\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z
|
|
31
|
-
).test(title)
|
|
33
|
+
`^(${parentTitlePrefix}|${childTitlePrefix})\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$`
|
|
34
|
+
).test(title);
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
export const Info = z
|
|
35
38
|
.object({
|
|
36
|
-
id: Identifier.schema(
|
|
39
|
+
id: Identifier.schema('session'),
|
|
37
40
|
projectID: z.string(),
|
|
38
41
|
directory: z.string(),
|
|
39
|
-
parentID: Identifier.schema(
|
|
42
|
+
parentID: Identifier.schema('session').optional(),
|
|
40
43
|
summary: z
|
|
41
44
|
.object({
|
|
42
45
|
additions: z.number(),
|
|
@@ -63,51 +66,51 @@ export namespace Session {
|
|
|
63
66
|
.optional(),
|
|
64
67
|
})
|
|
65
68
|
.meta({
|
|
66
|
-
ref:
|
|
67
|
-
})
|
|
68
|
-
export type Info = z.output<typeof Info
|
|
69
|
+
ref: 'Session',
|
|
70
|
+
});
|
|
71
|
+
export type Info = z.output<typeof Info>;
|
|
69
72
|
|
|
70
73
|
// ShareInfo removed - share not supported
|
|
71
74
|
|
|
72
75
|
export const Event = {
|
|
73
76
|
Created: Bus.event(
|
|
74
|
-
|
|
77
|
+
'session.created',
|
|
75
78
|
z.object({
|
|
76
79
|
info: Info,
|
|
77
|
-
})
|
|
80
|
+
})
|
|
78
81
|
),
|
|
79
82
|
Updated: Bus.event(
|
|
80
|
-
|
|
83
|
+
'session.updated',
|
|
81
84
|
z.object({
|
|
82
85
|
info: Info,
|
|
83
|
-
})
|
|
86
|
+
})
|
|
84
87
|
),
|
|
85
88
|
Deleted: Bus.event(
|
|
86
|
-
|
|
89
|
+
'session.deleted',
|
|
87
90
|
z.object({
|
|
88
91
|
info: Info,
|
|
89
|
-
})
|
|
92
|
+
})
|
|
90
93
|
),
|
|
91
94
|
Diff: Bus.event(
|
|
92
|
-
|
|
95
|
+
'session.diff',
|
|
93
96
|
z.object({
|
|
94
97
|
sessionID: z.string(),
|
|
95
98
|
diff: Snapshot.FileDiff.array(),
|
|
96
|
-
})
|
|
99
|
+
})
|
|
97
100
|
),
|
|
98
101
|
Error: Bus.event(
|
|
99
|
-
|
|
102
|
+
'session.error',
|
|
100
103
|
z.object({
|
|
101
104
|
sessionID: z.string().optional(),
|
|
102
105
|
error: MessageV2.Assistant.shape.error,
|
|
103
|
-
})
|
|
106
|
+
})
|
|
104
107
|
),
|
|
105
|
-
}
|
|
108
|
+
};
|
|
106
109
|
|
|
107
110
|
export const create = fn(
|
|
108
111
|
z
|
|
109
112
|
.object({
|
|
110
|
-
parentID: Identifier.schema(
|
|
113
|
+
parentID: Identifier.schema('session').optional(),
|
|
111
114
|
title: z.string().optional(),
|
|
112
115
|
})
|
|
113
116
|
.optional(),
|
|
@@ -116,51 +119,56 @@ export namespace Session {
|
|
|
116
119
|
parentID: input?.parentID,
|
|
117
120
|
directory: Instance.directory,
|
|
118
121
|
title: input?.title,
|
|
119
|
-
})
|
|
120
|
-
}
|
|
121
|
-
)
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
);
|
|
122
125
|
|
|
123
126
|
export const fork = fn(
|
|
124
127
|
z.object({
|
|
125
|
-
sessionID: Identifier.schema(
|
|
126
|
-
messageID: Identifier.schema(
|
|
128
|
+
sessionID: Identifier.schema('session'),
|
|
129
|
+
messageID: Identifier.schema('message').optional(),
|
|
127
130
|
}),
|
|
128
131
|
async (input) => {
|
|
129
132
|
const session = await createNext({
|
|
130
133
|
directory: Instance.directory,
|
|
131
|
-
})
|
|
132
|
-
const msgs = await messages({ sessionID: input.sessionID })
|
|
134
|
+
});
|
|
135
|
+
const msgs = await messages({ sessionID: input.sessionID });
|
|
133
136
|
for (const msg of msgs) {
|
|
134
|
-
if (input.messageID && msg.info.id >= input.messageID) break
|
|
137
|
+
if (input.messageID && msg.info.id >= input.messageID) break;
|
|
135
138
|
const cloned = await updateMessage({
|
|
136
139
|
...msg.info,
|
|
137
140
|
sessionID: session.id,
|
|
138
|
-
id: Identifier.ascending(
|
|
139
|
-
})
|
|
141
|
+
id: Identifier.ascending('message'),
|
|
142
|
+
});
|
|
140
143
|
|
|
141
144
|
for (const part of msg.parts) {
|
|
142
145
|
await updatePart({
|
|
143
146
|
...part,
|
|
144
|
-
id: Identifier.ascending(
|
|
147
|
+
id: Identifier.ascending('part'),
|
|
145
148
|
messageID: cloned.id,
|
|
146
149
|
sessionID: session.id,
|
|
147
|
-
})
|
|
150
|
+
});
|
|
148
151
|
}
|
|
149
152
|
}
|
|
150
|
-
return session
|
|
151
|
-
}
|
|
152
|
-
)
|
|
153
|
+
return session;
|
|
154
|
+
}
|
|
155
|
+
);
|
|
153
156
|
|
|
154
|
-
export const touch = fn(Identifier.schema(
|
|
157
|
+
export const touch = fn(Identifier.schema('session'), async (sessionID) => {
|
|
155
158
|
await update(sessionID, (draft) => {
|
|
156
|
-
draft.time.updated = Date.now()
|
|
157
|
-
})
|
|
158
|
-
})
|
|
159
|
+
draft.time.updated = Date.now();
|
|
160
|
+
});
|
|
161
|
+
});
|
|
159
162
|
|
|
160
|
-
export async function createNext(input: {
|
|
163
|
+
export async function createNext(input: {
|
|
164
|
+
id?: string;
|
|
165
|
+
title?: string;
|
|
166
|
+
parentID?: string;
|
|
167
|
+
directory: string;
|
|
168
|
+
}) {
|
|
161
169
|
const result: Info = {
|
|
162
|
-
id: Identifier.descending(
|
|
163
|
-
version:
|
|
170
|
+
id: Identifier.descending('session', input.id),
|
|
171
|
+
version: 'agent-cli-1.0.0',
|
|
164
172
|
projectID: Instance.project.id,
|
|
165
173
|
directory: input.directory,
|
|
166
174
|
parentID: input.parentID,
|
|
@@ -169,122 +177,128 @@ export namespace Session {
|
|
|
169
177
|
created: Date.now(),
|
|
170
178
|
updated: Date.now(),
|
|
171
179
|
},
|
|
172
|
-
}
|
|
173
|
-
log.info(
|
|
174
|
-
await Storage.write([
|
|
180
|
+
};
|
|
181
|
+
log.info('created', result);
|
|
182
|
+
await Storage.write(['session', Instance.project.id, result.id], result);
|
|
175
183
|
Bus.publish(Event.Created, {
|
|
176
184
|
info: result,
|
|
177
|
-
})
|
|
185
|
+
});
|
|
178
186
|
// Share not supported - removed auto-sharing
|
|
179
187
|
Bus.publish(Event.Updated, {
|
|
180
188
|
info: result,
|
|
181
|
-
})
|
|
182
|
-
return result
|
|
189
|
+
});
|
|
190
|
+
return result;
|
|
183
191
|
}
|
|
184
192
|
|
|
185
|
-
export const get = fn(Identifier.schema(
|
|
186
|
-
const read = await Storage.read<Info>([
|
|
187
|
-
return read as Info
|
|
188
|
-
})
|
|
193
|
+
export const get = fn(Identifier.schema('session'), async (id) => {
|
|
194
|
+
const read = await Storage.read<Info>(['session', Instance.project.id, id]);
|
|
195
|
+
return read as Info;
|
|
196
|
+
});
|
|
189
197
|
|
|
190
198
|
// getShare, share, unshare removed - share not supported
|
|
191
199
|
|
|
192
200
|
export async function update(id: string, editor: (session: Info) => void) {
|
|
193
|
-
const project = Instance.project
|
|
194
|
-
const result = await Storage.update<Info>(
|
|
195
|
-
|
|
196
|
-
draft
|
|
197
|
-
|
|
201
|
+
const project = Instance.project;
|
|
202
|
+
const result = await Storage.update<Info>(
|
|
203
|
+
['session', project.id, id],
|
|
204
|
+
(draft) => {
|
|
205
|
+
editor(draft);
|
|
206
|
+
draft.time.updated = Date.now();
|
|
207
|
+
}
|
|
208
|
+
);
|
|
198
209
|
Bus.publish(Event.Updated, {
|
|
199
210
|
info: result,
|
|
200
|
-
})
|
|
201
|
-
return result
|
|
211
|
+
});
|
|
212
|
+
return result;
|
|
202
213
|
}
|
|
203
214
|
|
|
204
|
-
export const diff = fn(Identifier.schema(
|
|
205
|
-
const diffs = await Storage.read<Snapshot.FileDiff[]>([
|
|
206
|
-
|
|
207
|
-
|
|
215
|
+
export const diff = fn(Identifier.schema('session'), async (sessionID) => {
|
|
216
|
+
const diffs = await Storage.read<Snapshot.FileDiff[]>([
|
|
217
|
+
'session_diff',
|
|
218
|
+
sessionID,
|
|
219
|
+
]);
|
|
220
|
+
return diffs ?? [];
|
|
221
|
+
});
|
|
208
222
|
|
|
209
223
|
export const messages = fn(
|
|
210
224
|
z.object({
|
|
211
|
-
sessionID: Identifier.schema(
|
|
225
|
+
sessionID: Identifier.schema('session'),
|
|
212
226
|
limit: z.number().optional(),
|
|
213
227
|
}),
|
|
214
228
|
async (input) => {
|
|
215
|
-
const result = [] as MessageV2.WithParts[]
|
|
229
|
+
const result = [] as MessageV2.WithParts[];
|
|
216
230
|
for await (const msg of MessageV2.stream(input.sessionID)) {
|
|
217
|
-
if (input.limit && result.length >= input.limit) break
|
|
218
|
-
result.push(msg)
|
|
231
|
+
if (input.limit && result.length >= input.limit) break;
|
|
232
|
+
result.push(msg);
|
|
219
233
|
}
|
|
220
|
-
result.reverse()
|
|
221
|
-
return result
|
|
222
|
-
}
|
|
223
|
-
)
|
|
234
|
+
result.reverse();
|
|
235
|
+
return result;
|
|
236
|
+
}
|
|
237
|
+
);
|
|
224
238
|
|
|
225
239
|
export async function* list() {
|
|
226
|
-
const project = Instance.project
|
|
227
|
-
for (const item of await Storage.list([
|
|
228
|
-
yield Storage.read<Info>(item)
|
|
240
|
+
const project = Instance.project;
|
|
241
|
+
for (const item of await Storage.list(['session', project.id])) {
|
|
242
|
+
yield Storage.read<Info>(item);
|
|
229
243
|
}
|
|
230
244
|
}
|
|
231
245
|
|
|
232
|
-
export const children = fn(Identifier.schema(
|
|
233
|
-
const project = Instance.project
|
|
234
|
-
const result = [] as Session.Info[]
|
|
235
|
-
for (const item of await Storage.list([
|
|
236
|
-
const session = await Storage.read<Info>(item)
|
|
237
|
-
if (session.parentID !== parentID) continue
|
|
238
|
-
result.push(session)
|
|
246
|
+
export const children = fn(Identifier.schema('session'), async (parentID) => {
|
|
247
|
+
const project = Instance.project;
|
|
248
|
+
const result = [] as Session.Info[];
|
|
249
|
+
for (const item of await Storage.list(['session', project.id])) {
|
|
250
|
+
const session = await Storage.read<Info>(item);
|
|
251
|
+
if (session.parentID !== parentID) continue;
|
|
252
|
+
result.push(session);
|
|
239
253
|
}
|
|
240
|
-
return result
|
|
241
|
-
})
|
|
254
|
+
return result;
|
|
255
|
+
});
|
|
242
256
|
|
|
243
|
-
export const remove = fn(Identifier.schema(
|
|
244
|
-
const project = Instance.project
|
|
257
|
+
export const remove = fn(Identifier.schema('session'), async (sessionID) => {
|
|
258
|
+
const project = Instance.project;
|
|
245
259
|
try {
|
|
246
|
-
const session = await get(sessionID)
|
|
260
|
+
const session = await get(sessionID);
|
|
247
261
|
for (const child of await children(sessionID)) {
|
|
248
|
-
await remove(child.id)
|
|
262
|
+
await remove(child.id);
|
|
249
263
|
}
|
|
250
264
|
// unshare removed - share not supported
|
|
251
|
-
for (const msg of await Storage.list([
|
|
252
|
-
for (const part of await Storage.list([
|
|
253
|
-
await Storage.remove(part)
|
|
265
|
+
for (const msg of await Storage.list(['message', sessionID])) {
|
|
266
|
+
for (const part of await Storage.list(['part', msg.at(-1)!])) {
|
|
267
|
+
await Storage.remove(part);
|
|
254
268
|
}
|
|
255
|
-
await Storage.remove(msg)
|
|
269
|
+
await Storage.remove(msg);
|
|
256
270
|
}
|
|
257
|
-
await Storage.remove([
|
|
271
|
+
await Storage.remove(['session', project.id, sessionID]);
|
|
258
272
|
Bus.publish(Event.Deleted, {
|
|
259
273
|
info: session,
|
|
260
|
-
})
|
|
274
|
+
});
|
|
261
275
|
} catch (e) {
|
|
262
|
-
log.error(e)
|
|
276
|
+
log.error(e);
|
|
263
277
|
}
|
|
264
|
-
})
|
|
278
|
+
});
|
|
265
279
|
|
|
266
280
|
export const updateMessage = fn(MessageV2.Info, async (msg) => {
|
|
267
|
-
await Storage.write([
|
|
281
|
+
await Storage.write(['message', msg.sessionID, msg.id], msg);
|
|
268
282
|
Bus.publish(MessageV2.Event.Updated, {
|
|
269
283
|
info: msg,
|
|
270
|
-
})
|
|
271
|
-
return msg
|
|
272
|
-
})
|
|
284
|
+
});
|
|
285
|
+
return msg;
|
|
286
|
+
});
|
|
273
287
|
|
|
274
288
|
export const removeMessage = fn(
|
|
275
289
|
z.object({
|
|
276
|
-
sessionID: Identifier.schema(
|
|
277
|
-
messageID: Identifier.schema(
|
|
290
|
+
sessionID: Identifier.schema('session'),
|
|
291
|
+
messageID: Identifier.schema('message'),
|
|
278
292
|
}),
|
|
279
293
|
async (input) => {
|
|
280
|
-
await Storage.remove([
|
|
294
|
+
await Storage.remove(['message', input.sessionID, input.messageID]);
|
|
281
295
|
Bus.publish(MessageV2.Event.Removed, {
|
|
282
296
|
sessionID: input.sessionID,
|
|
283
297
|
messageID: input.messageID,
|
|
284
|
-
})
|
|
285
|
-
return input.messageID
|
|
286
|
-
}
|
|
287
|
-
)
|
|
298
|
+
});
|
|
299
|
+
return input.messageID;
|
|
300
|
+
}
|
|
301
|
+
);
|
|
288
302
|
|
|
289
303
|
const UpdatePartInput = z.union([
|
|
290
304
|
MessageV2.Part,
|
|
@@ -296,18 +310,18 @@ export namespace Session {
|
|
|
296
310
|
part: MessageV2.ReasoningPart,
|
|
297
311
|
delta: z.string(),
|
|
298
312
|
}),
|
|
299
|
-
])
|
|
313
|
+
]);
|
|
300
314
|
|
|
301
315
|
export const updatePart = fn(UpdatePartInput, async (input) => {
|
|
302
|
-
const part =
|
|
303
|
-
const delta =
|
|
304
|
-
await Storage.write([
|
|
316
|
+
const part = 'delta' in input ? input.part : input;
|
|
317
|
+
const delta = 'delta' in input ? input.delta : undefined;
|
|
318
|
+
await Storage.write(['part', part.messageID, part.id], part);
|
|
305
319
|
Bus.publish(MessageV2.Event.PartUpdated, {
|
|
306
320
|
part,
|
|
307
321
|
delta,
|
|
308
|
-
})
|
|
309
|
-
return part
|
|
310
|
-
})
|
|
322
|
+
});
|
|
323
|
+
return part;
|
|
324
|
+
});
|
|
311
325
|
|
|
312
326
|
export const getUsage = fn(
|
|
313
327
|
z.object({
|
|
@@ -316,65 +330,84 @@ export namespace Session {
|
|
|
316
330
|
metadata: z.custom<ProviderMetadata>().optional(),
|
|
317
331
|
}),
|
|
318
332
|
(input) => {
|
|
319
|
-
const cachedInputTokens = input.usage.cachedInputTokens ?? 0
|
|
320
|
-
const excludesCachedTokens = !!(
|
|
333
|
+
const cachedInputTokens = input.usage.cachedInputTokens ?? 0;
|
|
334
|
+
const excludesCachedTokens = !!(
|
|
335
|
+
input.metadata?.['anthropic'] || input.metadata?.['bedrock']
|
|
336
|
+
);
|
|
321
337
|
const adjustedInputTokens = excludesCachedTokens
|
|
322
338
|
? (input.usage.inputTokens ?? 0)
|
|
323
|
-
: (input.usage.inputTokens ?? 0) - cachedInputTokens
|
|
339
|
+
: (input.usage.inputTokens ?? 0) - cachedInputTokens;
|
|
324
340
|
|
|
325
341
|
const tokens = {
|
|
326
342
|
input: adjustedInputTokens,
|
|
327
343
|
output: input.usage.outputTokens ?? 0,
|
|
328
344
|
reasoning: input.usage?.reasoningTokens ?? 0,
|
|
329
345
|
cache: {
|
|
330
|
-
write: (input.metadata?.[
|
|
346
|
+
write: (input.metadata?.['anthropic']?.['cacheCreationInputTokens'] ??
|
|
331
347
|
// @ts-expect-error
|
|
332
|
-
input.metadata?.[
|
|
348
|
+
input.metadata?.['bedrock']?.['usage']?.['cacheWriteInputTokens'] ??
|
|
333
349
|
0) as number,
|
|
334
350
|
read: cachedInputTokens,
|
|
335
351
|
},
|
|
336
|
-
}
|
|
352
|
+
};
|
|
337
353
|
|
|
338
354
|
const costInfo =
|
|
339
|
-
input.model.cost?.context_over_200k &&
|
|
355
|
+
input.model.cost?.context_over_200k &&
|
|
356
|
+
tokens.input + tokens.cache.read > 200_000
|
|
340
357
|
? input.model.cost.context_over_200k
|
|
341
|
-
: input.model.cost
|
|
358
|
+
: input.model.cost;
|
|
342
359
|
return {
|
|
343
360
|
cost: new Decimal(0)
|
|
344
|
-
.add(
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
.add(
|
|
361
|
+
.add(
|
|
362
|
+
new Decimal(tokens.input).mul(costInfo?.input ?? 0).div(1_000_000)
|
|
363
|
+
)
|
|
364
|
+
.add(
|
|
365
|
+
new Decimal(tokens.output).mul(costInfo?.output ?? 0).div(1_000_000)
|
|
366
|
+
)
|
|
367
|
+
.add(
|
|
368
|
+
new Decimal(tokens.cache.read)
|
|
369
|
+
.mul(costInfo?.cache_read ?? 0)
|
|
370
|
+
.div(1_000_000)
|
|
371
|
+
)
|
|
372
|
+
.add(
|
|
373
|
+
new Decimal(tokens.cache.write)
|
|
374
|
+
.mul(costInfo?.cache_write ?? 0)
|
|
375
|
+
.div(1_000_000)
|
|
376
|
+
)
|
|
348
377
|
// TODO: update models.dev to have better pricing model, for now:
|
|
349
378
|
// charge reasoning tokens at the same rate as output tokens
|
|
350
|
-
.add(
|
|
379
|
+
.add(
|
|
380
|
+
new Decimal(tokens.reasoning)
|
|
381
|
+
.mul(costInfo?.output ?? 0)
|
|
382
|
+
.div(1_000_000)
|
|
383
|
+
)
|
|
351
384
|
.toNumber(),
|
|
352
385
|
tokens,
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
)
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
);
|
|
356
389
|
|
|
357
390
|
export class BusyError extends Error {
|
|
358
391
|
constructor(public readonly sessionID: string) {
|
|
359
|
-
super(`Session ${sessionID} is busy`)
|
|
392
|
+
super(`Session ${sessionID} is busy`);
|
|
360
393
|
}
|
|
361
394
|
}
|
|
362
395
|
|
|
363
396
|
export const initialize = fn(
|
|
364
397
|
z.object({
|
|
365
|
-
sessionID: Identifier.schema(
|
|
398
|
+
sessionID: Identifier.schema('session'),
|
|
366
399
|
modelID: z.string(),
|
|
367
400
|
providerID: z.string(),
|
|
368
|
-
messageID: Identifier.schema(
|
|
401
|
+
messageID: Identifier.schema('message'),
|
|
369
402
|
}),
|
|
370
403
|
async (input) => {
|
|
371
404
|
await SessionPrompt.command({
|
|
372
405
|
sessionID: input.sessionID,
|
|
373
406
|
messageID: input.messageID,
|
|
374
|
-
model: input.providerID +
|
|
407
|
+
model: input.providerID + '/' + input.modelID,
|
|
375
408
|
command: Command.Default.INIT,
|
|
376
|
-
arguments:
|
|
377
|
-
})
|
|
378
|
-
}
|
|
379
|
-
)
|
|
409
|
+
arguments: '',
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
);
|
|
380
413
|
}
|