@timefly/opencode-plugin 0.2.1 → 0.2.3
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 +68 -2
- package/dist/event-handlers.d.ts.map +1 -1
- package/dist/event-handlers.js +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -18
- package/dist/read-chat-params.d.ts +52 -0
- package/dist/read-chat-params.d.ts.map +1 -0
- package/dist/read-chat-params.js +21 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -180,7 +180,7 @@ OpenCode hooks → @timefly/opencode-plugin → @timefly/ai-sdk
|
|
|
180
180
|
→ POST /ai/sync (gzip JSON, Bearer token)
|
|
181
181
|
→ Gateway auth + Supporter check
|
|
182
182
|
→ Ingest queue (Redis)
|
|
183
|
-
→ Worker (every 5s) → ClickHouse
|
|
183
|
+
→ Worker (every 5s) → ClickHouse activity_events (ai.* activities)
|
|
184
184
|
→ Dashboard GET /analytics/ai-usage
|
|
185
185
|
```
|
|
186
186
|
|
|
@@ -230,10 +230,76 @@ OpenCode installs npm plugins automatically at startup via Bun.
|
|
|
230
230
|
|
|
231
231
|
## Events captured
|
|
232
232
|
|
|
233
|
+
Based on OpenCode source (`packages/opencode`, `@opencode-ai/plugin` hooks, and `@opencode-ai/sdk` event types). We only emit metadata — never prompts, tool args, or file contents.
|
|
234
|
+
|
|
235
|
+
### Plugin hooks we use
|
|
236
|
+
|
|
237
|
+
| Hook | When it fires (OpenCode source) | TimeFly event |
|
|
238
|
+
|------|----------------------------------|---------------|
|
|
239
|
+
| `event` | Bus events forwarded from `EventV2Bridge` to all plugins | see bus table below |
|
|
240
|
+
| `chat.params` | Before every LLM call (`LLMRequestPrep.prepare`) | `llm_request` |
|
|
241
|
+
| `tool.execute.before` | Before built-in, MCP, and registry tools run (`SessionTools.resolve`) | `tool_call` |
|
|
242
|
+
| `tool.execute.after` | After tool completes (same path) | `tool_result` |
|
|
243
|
+
| `experimental.session.compacting` | Before compaction LLM call (`SessionCompaction.process`) | `compaction` |
|
|
244
|
+
|
|
245
|
+
### Bus events we handle (`event` hook)
|
|
246
|
+
|
|
247
|
+
| OpenCode event | Status | TimeFly event | Data captured |
|
|
248
|
+
|----------------|--------|---------------|---------------|
|
|
249
|
+
| `session.created` | Active | `session_start` | title, project, directory |
|
|
250
|
+
| `session.status` (`type: idle`) | Preferred | `session_end` | session token/tool/request totals |
|
|
251
|
+
| `session.idle` | Deprecated alias | `session_end` | same as above |
|
|
252
|
+
| `message.updated` (assistant, completed) | Active | `turn_complete` + `llm_response` | tokens, cost, duration, finish reason |
|
|
253
|
+
| `message.updated` (user) | Active | `llm_request` | model, agent (metadata only) |
|
|
254
|
+
| `message.part.updated` (`step-finish`) | Active | `llm_response` | per-step tokens, cost |
|
|
255
|
+
| `message.part.updated` (`retry`) | Active | `error` | retry attempt |
|
|
256
|
+
| `message.part.updated` (`compaction`) | Active | `compaction` | auto/manual flag |
|
|
257
|
+
| `session.compacted` | Active | `compaction` | session id |
|
|
258
|
+
| `session.error` | Active | `error` | error name/message |
|
|
259
|
+
| `command.executed` | Active | `tool_call` | command name (as `command:*`) |
|
|
260
|
+
|
|
261
|
+
### Bus events we intentionally skip
|
|
262
|
+
|
|
263
|
+
| OpenCode event | Why not tracked |
|
|
264
|
+
|----------------|-----------------|
|
|
265
|
+
| `message.part.updated` (`text`, `reasoning`, `tool`, …) | Would expose prompt/response/tool args |
|
|
266
|
+
| `message.removed`, `message.part.removed` | Deletion only — no usage signal |
|
|
267
|
+
| `session.updated`, `session.deleted`, `session.diff` | Metadata or file diffs — not AI usage |
|
|
268
|
+
| `file.edited`, `file.watcher.updated` | File paths/content |
|
|
269
|
+
| `permission.asked`, `permission.replied` | No token/model signal |
|
|
270
|
+
| `todo.updated` | Task list text |
|
|
271
|
+
| `lsp.*`, `pty.*`, `tui.*`, `installation.*`, `server.*` | IDE/infra — not LLM usage |
|
|
272
|
+
|
|
273
|
+
### Hooks we do not use (available in OpenCode, not needed for usage telemetry)
|
|
274
|
+
|
|
275
|
+
| Hook | Reason |
|
|
276
|
+
|------|--------|
|
|
277
|
+
| `chat.message` | Full user message + parts — privacy |
|
|
278
|
+
| `chat.headers` | Auth headers — security |
|
|
279
|
+
| `shell.env` | Environment variables — secrets risk |
|
|
280
|
+
| `permission.ask` | Could track denials; not implemented yet |
|
|
281
|
+
| `command.execute.before` | Parts contain prompt fragments |
|
|
282
|
+
| `experimental.chat.messages.transform` | Full message history |
|
|
283
|
+
| `experimental.compaction.autocontinue` | No extra telemetry beyond compaction events |
|
|
284
|
+
| `tool` (custom tools) | Execution still flows through `tool.execute.*` |
|
|
285
|
+
|
|
286
|
+
### Known limitations
|
|
287
|
+
|
|
288
|
+
| Topic | Detail |
|
|
289
|
+
|-------|--------|
|
|
290
|
+
| **Custom providers** (e.g. `nan`) | OpenCode runtime passes flat `Provider.Info` (`provider.id`) via `LLMRequestPrep.prepare` — not `provider.info.id`. Plugin reads both runtime and typed `ProviderContext` shapes. |
|
|
291
|
+
| **Token counts** | Require provider to report usage. If `message.updated` lacks token fields, turn events are skipped (no crash). |
|
|
292
|
+
| **Provider-side tools** | Tools executed inside the provider (`providerExecuted`) may not hit `tool.execute.*` — no tool events for those. |
|
|
293
|
+
| **Multi-step turns** | `step-finish` parts can emit extra `llm_response` events; message-level `turn_complete` deduplicates by message id. |
|
|
294
|
+
| **`session.idle` vs `session.status`** | OpenCode marks `session.idle` deprecated; we handle both. |
|
|
295
|
+
| **v2 event system** | OpenCode is migrating to `session.next.*` internally; plugins still receive v1 bus types above via the bridge. |
|
|
296
|
+
|
|
297
|
+
### Quick reference (captured signals)
|
|
298
|
+
|
|
233
299
|
| OpenCode signal | TimeFly `eventType` | Data |
|
|
234
300
|
|-----------------|---------------------|------|
|
|
235
301
|
| `session.created` | `session_start` | title, project, directory |
|
|
236
|
-
| `session.idle` | `session_end` | session token/tool/request totals |
|
|
302
|
+
| `session.status` / `session.idle` | `session_end` | session token/tool/request totals |
|
|
237
303
|
| `chat.params` | `llm_request` | model, provider, agent, temperature |
|
|
238
304
|
| `message.updated` (assistant, completed) | `turn_complete` + `llm_response` | tokens, duration, tokens/s, cost |
|
|
239
305
|
| `message.part.updated` (step-finish) | `llm_response` | per-step tokens |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-handlers.d.ts","sourceRoot":"","sources":["../src/event-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAiBvD,OAAO,EASN,KAAK,gBAAgB,EACrB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAG/D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,SAAS,CAAC,CAAA;AAKxE,eAAO,MAAM,oBAAoB,GAAI,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,cAAc,KAAG,OAAO,CAAC,IAAI,CAapH,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC7B,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,SAAS,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC9C,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAad,CAAA;AAED,eAAO,MAAM,oBAAoB,GAChC,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,SAAS,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC9C,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAwCd,CAAA;AAED,eAAO,MAAM,wBAAwB,GACpC,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,SAAS,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC9C,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAiCd,CAAA;AAED,eAAO,MAAM,sBAAsB,GAClC,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAQd,CAAA;AAED,eAAO,MAAM,kBAAkB,GAC9B,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAmBd,CAAA;AAED,eAAO,MAAM,qBAAqB,GACjC,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAad,CAAA;AAED,eAAO,MAAM,cAAc,GAC1B,OAAO,gBAAgB,EACvB,SAAS,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC9C,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"event-handlers.d.ts","sourceRoot":"","sources":["../src/event-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAiBvD,OAAO,EASN,KAAK,gBAAgB,EACrB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAG/D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,SAAS,CAAC,CAAA;AAKxE,eAAO,MAAM,oBAAoB,GAAI,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,cAAc,KAAG,OAAO,CAAC,IAAI,CAapH,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC7B,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,SAAS,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC9C,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAad,CAAA;AAED,eAAO,MAAM,oBAAoB,GAChC,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,SAAS,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC9C,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAwCd,CAAA;AAED,eAAO,MAAM,wBAAwB,GACpC,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,SAAS,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC9C,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAiCd,CAAA;AAED,eAAO,MAAM,sBAAsB,GAClC,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAQd,CAAA;AAED,eAAO,MAAM,kBAAkB,GAC9B,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAmBd,CAAA;AAED,eAAO,MAAM,qBAAqB,GACjC,iBAAiB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAad,CAAA;AAED,eAAO,MAAM,cAAc,GAC1B,OAAO,gBAAgB,EACvB,SAAS,UAAU,CAAC,OAAO,kBAAkB,CAAC,EAC9C,SAAS,cAAc,KACrB,OAAO,CAAC,IAAI,CAkCd,CAAA"}
|
package/dist/event-handlers.js
CHANGED
|
@@ -127,6 +127,13 @@ export const handleBusEvent = (event, tracker, publish) => {
|
|
|
127
127
|
switch (event.type) {
|
|
128
128
|
case 'session.created':
|
|
129
129
|
return handleSessionCreated(eventProperties, publish);
|
|
130
|
+
case 'session.status': {
|
|
131
|
+
const statusRecord = isRecord(eventProperties.status) ? eventProperties.status : undefined;
|
|
132
|
+
if (statusRecord?.type !== 'idle') {
|
|
133
|
+
return Promise.resolve();
|
|
134
|
+
}
|
|
135
|
+
return handleSessionIdle(eventProperties, tracker, publish);
|
|
136
|
+
}
|
|
130
137
|
case 'session.idle':
|
|
131
138
|
return handleSessionIdle(eventProperties, tracker, publish);
|
|
132
139
|
case 'message.updated':
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAgBjD,eAAO,MAAM,qBAAqB,EAAE,MA+DnC,CAAA;AAED,eAAe,qBAAqB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -2,33 +2,49 @@ import { createEventTracker } from './event-tracker.js';
|
|
|
2
2
|
import { handleBusEvent } from './event-handlers.js';
|
|
3
3
|
import { mapCompactionInput, mapLlmRequestInput, mapToolCallInput, mapToolResultInput } from './map-opencode-event.js';
|
|
4
4
|
import { createEventPublisher } from './publish-events.js';
|
|
5
|
+
import { resolveChatParams } from './read-chat-params.js';
|
|
5
6
|
import packageJson from '../package.json' with { type: 'json' };
|
|
6
7
|
const PLUGIN_VERSION = packageJson.version;
|
|
8
|
+
const runHookSafely = (run) => Promise.resolve()
|
|
9
|
+
.then(run)
|
|
10
|
+
.catch(() => undefined);
|
|
7
11
|
export const timeflyOpenCodePlugin = ({ client }) => {
|
|
8
12
|
const tracker = createEventTracker();
|
|
9
13
|
const publisher = createEventPublisher(client, PLUGIN_VERSION);
|
|
10
|
-
return
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
return client.app
|
|
15
|
+
.log({
|
|
16
|
+
body: {
|
|
17
|
+
service: 'timefly-opencode-plugin',
|
|
18
|
+
level: 'info',
|
|
19
|
+
message: `TimeFly telemetry active (v${PLUGIN_VERSION})`,
|
|
20
|
+
extra: { source: 'opencode' }
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
.then(() => undefined)
|
|
24
|
+
.catch(() => undefined)
|
|
25
|
+
.then(() => Promise.resolve({
|
|
26
|
+
event: (input) => runHookSafely(() => handleBusEvent(input.event, tracker, publisher.publish)),
|
|
27
|
+
'chat.params': (input, output) => runHookSafely(() => {
|
|
13
28
|
tracker.recordSessionStats(input.sessionID, { requestCount: 1 });
|
|
29
|
+
const resolvedParams = resolveChatParams(input, output);
|
|
14
30
|
return publisher.publish([
|
|
15
31
|
mapLlmRequestInput({
|
|
16
|
-
sessionID:
|
|
17
|
-
agent:
|
|
18
|
-
providerId:
|
|
19
|
-
modelId:
|
|
20
|
-
providerSource:
|
|
21
|
-
temperature:
|
|
22
|
-
topP:
|
|
23
|
-
maxOutputTokens:
|
|
32
|
+
sessionID: resolvedParams.sessionID,
|
|
33
|
+
agent: resolvedParams.agent,
|
|
34
|
+
providerId: resolvedParams.providerId,
|
|
35
|
+
modelId: resolvedParams.modelId,
|
|
36
|
+
providerSource: resolvedParams.providerSource,
|
|
37
|
+
temperature: resolvedParams.temperature,
|
|
38
|
+
topP: resolvedParams.topP,
|
|
39
|
+
maxOutputTokens: resolvedParams.maxOutputTokens
|
|
24
40
|
})
|
|
25
41
|
]);
|
|
26
|
-
},
|
|
27
|
-
'tool.execute.before': (input) => {
|
|
42
|
+
}),
|
|
43
|
+
'tool.execute.before': (input) => runHookSafely(() => {
|
|
28
44
|
tracker.recordSessionStats(input.sessionID, { toolCallCount: 1 });
|
|
29
45
|
return publisher.publish([mapToolCallInput(input)]);
|
|
30
|
-
},
|
|
31
|
-
'tool.execute.after': (input, output) => publisher.publish([
|
|
46
|
+
}),
|
|
47
|
+
'tool.execute.after': (input, output) => runHookSafely(() => publisher.publish([
|
|
32
48
|
mapToolResultInput({
|
|
33
49
|
sessionID: input.sessionID,
|
|
34
50
|
tool: input.tool,
|
|
@@ -36,8 +52,8 @@ export const timeflyOpenCodePlugin = ({ client }) => {
|
|
|
36
52
|
hasOutput: Boolean(output.output),
|
|
37
53
|
outputLength: output.output.length
|
|
38
54
|
})
|
|
39
|
-
]),
|
|
40
|
-
'experimental.session.compacting': (input) => publisher.publish([mapCompactionInput(input.sessionID)])
|
|
41
|
-
});
|
|
55
|
+
])),
|
|
56
|
+
'experimental.session.compacting': (input) => runHookSafely(() => publisher.publish([mapCompactionInput(input.sessionID)]))
|
|
57
|
+
}));
|
|
42
58
|
};
|
|
43
59
|
export default timeflyOpenCodePlugin;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode runtime passes flat `Provider.Info` to `chat.params`:
|
|
3
|
+
* `packages/opencode/src/session/llm/request.ts` → `provider: input.provider`
|
|
4
|
+
*
|
|
5
|
+
* Shape: `{ id, name, source, env, options, models }` — id is at the top level.
|
|
6
|
+
*
|
|
7
|
+
* `@opencode-ai/plugin` types document `ProviderContext` (`{ source, info, options }`)
|
|
8
|
+
* which does not match current runtime (anomalyco/opencode#20562). We accept both.
|
|
9
|
+
*
|
|
10
|
+
* Model shape: `Provider.Model` → `{ id, providerID, … }`.
|
|
11
|
+
*/
|
|
12
|
+
export type OpenCodeProviderInfo = {
|
|
13
|
+
id: string;
|
|
14
|
+
name?: string;
|
|
15
|
+
source?: 'env' | 'config' | 'custom' | 'api' | string;
|
|
16
|
+
options?: Record<string, unknown>;
|
|
17
|
+
};
|
|
18
|
+
export type OpenCodeProviderContext = {
|
|
19
|
+
source?: 'env' | 'config' | 'custom' | 'api' | string;
|
|
20
|
+
info?: {
|
|
21
|
+
id?: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
};
|
|
24
|
+
options?: Record<string, unknown>;
|
|
25
|
+
};
|
|
26
|
+
export type OpenCodeModel = {
|
|
27
|
+
id: string;
|
|
28
|
+
providerID: string;
|
|
29
|
+
};
|
|
30
|
+
export type ChatParamsInput = {
|
|
31
|
+
sessionID: string;
|
|
32
|
+
agent: string;
|
|
33
|
+
model?: OpenCodeModel;
|
|
34
|
+
provider?: OpenCodeProviderInfo | OpenCodeProviderContext;
|
|
35
|
+
};
|
|
36
|
+
export type ChatParamsOutput = {
|
|
37
|
+
temperature: number;
|
|
38
|
+
topP: number;
|
|
39
|
+
maxOutputTokens?: number;
|
|
40
|
+
};
|
|
41
|
+
export type ResolvedChatParams = {
|
|
42
|
+
sessionID: string;
|
|
43
|
+
agent: string;
|
|
44
|
+
providerId: string;
|
|
45
|
+
modelId: string;
|
|
46
|
+
providerSource: string;
|
|
47
|
+
temperature: number;
|
|
48
|
+
topP: number;
|
|
49
|
+
maxOutputTokens?: number;
|
|
50
|
+
};
|
|
51
|
+
export declare const resolveChatParams: (input: ChatParamsInput, output: ChatParamsOutput) => ResolvedChatParams;
|
|
52
|
+
//# sourceMappingURL=read-chat-params.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-chat-params.d.ts","sourceRoot":"","sources":["../src/read-chat-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAA;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACrC,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAA;IACrD,IAAI,CAAC,EAAE;QACN,EAAE,CAAC,EAAE,MAAM,CAAA;QACX,IAAI,CAAC,EAAE,MAAM,CAAA;KACb,CAAA;IACD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,QAAQ,CAAC,EAAE,oBAAoB,GAAG,uBAAuB,CAAA;CACzD,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAiBD,eAAO,MAAM,iBAAiB,GAAI,OAAO,eAAe,EAAE,QAAQ,gBAAgB,KAAG,kBASnF,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const readProviderId = (provider, model) => {
|
|
2
|
+
if (provider && 'id' in provider && typeof provider.id === 'string' && provider.id.length > 0) {
|
|
3
|
+
return provider.id;
|
|
4
|
+
}
|
|
5
|
+
const nestedProviderId = provider && 'info' in provider ? provider.info?.id : undefined;
|
|
6
|
+
if (typeof nestedProviderId === 'string' && nestedProviderId.length > 0) {
|
|
7
|
+
return nestedProviderId;
|
|
8
|
+
}
|
|
9
|
+
return model?.providerID ?? 'unknown';
|
|
10
|
+
};
|
|
11
|
+
const readProviderSource = (provider) => provider?.source ?? 'unknown';
|
|
12
|
+
export const resolveChatParams = (input, output) => ({
|
|
13
|
+
sessionID: input.sessionID,
|
|
14
|
+
agent: input.agent,
|
|
15
|
+
providerId: readProviderId(input.provider, input.model),
|
|
16
|
+
modelId: input.model?.id ?? 'unknown',
|
|
17
|
+
providerSource: readProviderSource(input.provider),
|
|
18
|
+
temperature: output.temperature,
|
|
19
|
+
topP: output.topP,
|
|
20
|
+
maxOutputTokens: output.maxOutputTokens
|
|
21
|
+
});
|