| author | |
| committer | |
| log | fcb1a50ee42a051ed1c0605f688cb6c94f043838 |
| tree | 3f0593d72ba31030228da26d7d066cb20dd98fa4 |
| parent | ec3778bbf4a5d8726cff22bddfcba82cd1c6ebde |
5 files changed, 19 insertions(+), 17 deletions(-)
apps/server/src/index.ts+2-2| ... | @@ -10,7 +10,7 @@ import { version } from "../package.json" with { type: "json" }; | ... | @@ -10,7 +10,7 @@ import { version } from "../package.json" with { type: "json" }; |
| 10 | import { ServerLive } from "./wsServer"; | 10 | import { ServerLive } from "./wsServer"; |
| 11 | import { NetService } from "@t3tools/shared/Net"; | 11 | import { NetService } from "@t3tools/shared/Net"; |
| 12 | import { AnalyticsServiceLayerLive } from "./telemetry/Layers/AnalyticsService"; | 12 | import { AnalyticsServiceLayerLive } from "./telemetry/Layers/AnalyticsService"; |
| 13 | import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient"; | 13 | import { FetchHttpClient } from "effect/unstable/http"; |
| 14 | 14 | ||
| 15 | const RuntimeLayer = Layer.empty.pipe( | 15 | const RuntimeLayer = Layer.empty.pipe( |
| 16 | Layer.provideMerge(CliConfig.layer), | 16 | Layer.provideMerge(CliConfig.layer), |
| ... | @@ -19,7 +19,7 @@ const RuntimeLayer = Layer.empty.pipe( | ... | @@ -19,7 +19,7 @@ const RuntimeLayer = Layer.empty.pipe( |
| 19 | Layer.provideMerge(OpenLive), | 19 | Layer.provideMerge(OpenLive), |
| 20 | Layer.provideMerge(NetService.layer), | 20 | Layer.provideMerge(NetService.layer), |
| 21 | Layer.provideMerge(NodeServices.layer), | 21 | Layer.provideMerge(NodeServices.layer), |
| 22 | Layer.provideMerge(NodeHttpClient.layerUndici), | 22 | Layer.provideMerge(FetchHttpClient.layer), |
| 23 | ); | 23 | ); |
| 24 | 24 | ||
| 25 | Command.run(t3Cli, { version }).pipe(Effect.provide(RuntimeLayer), NodeRuntime.runMain); | 25 | Command.run(t3Cli, { version }).pipe(Effect.provide(RuntimeLayer), NodeRuntime.runMain); |
apps/server/src/provider/Layers/ProviderService.ts+2-8| ... | @@ -276,8 +276,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => | ... | @@ -276,8 +276,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => |
| 276 | yield* upsertSessionBinding(session, threadId); | 276 | yield* upsertSessionBinding(session, threadId); |
| 277 | yield* analytics.record("provider.session.started", { | 277 | yield* analytics.record("provider.session.started", { |
| 278 | provider: session.provider, | 278 | provider: session.provider, |
| 279 | hasResumeCursor: session.resumeCursor !== undefined, | ||
| 280 | hasCwd: typeof input.cwd === "string" && input.cwd.trim().length > 0, | ||
| 281 | approvalPolicy: input.approvalPolicy, | 279 | approvalPolicy: input.approvalPolicy, |
| 282 | sandboxMode: input.sandboxMode, | 280 | sandboxMode: input.sandboxMode, |
| 283 | }); | 281 | }); |
| ... | @@ -322,8 +320,8 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => | ... | @@ -322,8 +320,8 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => |
| 322 | }); | 320 | }); |
| 323 | yield* analytics.record("provider.turn.sent", { | 321 | yield* analytics.record("provider.turn.sent", { |
| 324 | provider: routed.adapter.provider, | 322 | provider: routed.adapter.provider, |
| 325 | attachmentCount: input.attachments.length, | 323 | model: input.model, |
| 326 | hasInput: typeof input.input === "string" && input.input.trim().length > 0, | 324 | effort: input.effort, |
| 327 | }); | 325 | }); |
| 328 | return turn; | 326 | return turn; |
| 329 | }); | 327 | }); |
| ... | @@ -343,7 +341,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => | ... | @@ -343,7 +341,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => |
| 343 | yield* routed.adapter.interruptTurn(routed.threadId, input.turnId); | 341 | yield* routed.adapter.interruptTurn(routed.threadId, input.turnId); |
| 344 | yield* analytics.record("provider.turn.interrupted", { | 342 | yield* analytics.record("provider.turn.interrupted", { |
| 345 | provider: routed.adapter.provider, | 343 | provider: routed.adapter.provider, |
| 346 | hasTurnId: input.turnId !== undefined, | ||
| 347 | }); | 344 | }); |
| 348 | }); | 345 | }); |
| 349 | 346 | ||
| ... | @@ -379,8 +376,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => | ... | @@ -379,8 +376,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => |
| 379 | allowRecovery: true, | 376 | allowRecovery: true, |
| 380 | }); | 377 | }); |
| 381 | yield* routed.adapter.respondToUserInput(routed.threadId, input.requestId, input.answers); | 378 | yield* routed.adapter.respondToUserInput(routed.threadId, input.requestId, input.answers); |
| 382 | yield* analytics.record("provider.user_input.responded", { | ||
| 383 | provider: routed.adapter.provider, | ||
| 384 | }); | 379 | }); |
| 385 | }); | 380 | }); |
| 386 | 381 | ||
| ... | @@ -402,7 +397,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => | ... | @@ -402,7 +397,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) => |
| 402 | yield* directory.remove(input.threadId); | 397 | yield* directory.remove(input.threadId); |
| 403 | yield* analytics.record("provider.session.stopped", { | 398 | yield* analytics.record("provider.session.stopped", { |
| 404 | provider: routed.adapter.provider, | 399 | provider: routed.adapter.provider, |
| 405 | wasActive: routed.isActive, | ||
| 406 | }); | 400 | }); |
| 407 | }); | 401 | }); |
| 408 | 402 |
apps/server/src/telemetry/Layers/AnalyticsService.ts+5-1| ... | @@ -126,7 +126,11 @@ const makeAnalyticsService = Effect.gen(function* () { | ... | @@ -126,7 +126,11 @@ const makeAnalyticsService = Effect.gen(function* () { |
| 126 | } | 126 | } |
| 127 | }); | 127 | }); |
| 128 | 128 | ||
| 129 | yield* Effect.forever(flush, { disableYield: true }).pipe(Effect.forkDetach); | 129 | yield* Effect.forever(Effect.sleep(1000).pipe(Effect.flatMap(() => flush)), { |
| 130 | disableYield: true, | ||
| 131 | }).pipe(Effect.forkDetach); | ||
| 132 | |||
| 133 | yield* Effect.addFinalizer(() => flush); | ||
| 130 | 134 | ||
| 131 | return { | 135 | return { |
| 132 | record, | 136 | record, |
apps/server/src/telemetry/Services/AnalyticsService.ts+7-2| ... | @@ -6,7 +6,7 @@ | ... | @@ -6,7 +6,7 @@ |
| 6 | * | 6 | * |
| 7 | * @module AnalyticsService | 7 | * @module AnalyticsService |
| 8 | */ | 8 | */ |
| 9 | import { Effect, ServiceMap } from "effect"; | 9 | import { Effect, Layer, ServiceMap } from "effect"; |
| 10 | 10 | ||
| 11 | export interface AnalyticsServiceShape { | 11 | export interface AnalyticsServiceShape { |
| 12 | /** | 12 | /** |
| ... | @@ -25,4 +25,9 @@ export interface AnalyticsServiceShape { | ... | @@ -25,4 +25,9 @@ export interface AnalyticsServiceShape { |
| 25 | 25 | ||
| 26 | export class AnalyticsService extends ServiceMap.Service<AnalyticsService, AnalyticsServiceShape>()( | 26 | export class AnalyticsService extends ServiceMap.Service<AnalyticsService, AnalyticsServiceShape>()( |
| 27 | "t3/telemetry/Services/AnalyticsService", | 27 | "t3/telemetry/Services/AnalyticsService", |
| 28 | ) {} | 28 | ) { |
| 29 | static readonly layerTest = Layer.succeed(AnalyticsService, { | ||
| 30 | record: () => Effect.void, | ||
| 31 | flush: Effect.void, | ||
| 32 | }); | ||
| 33 | } |
apps/server/src/wsServer.test.ts+3-4| ... | @@ -50,8 +50,7 @@ import type { GitCoreShape } from "./git/Services/GitCore.ts"; | ... | @@ -50,8 +50,7 @@ import type { GitCoreShape } from "./git/Services/GitCore.ts"; |
| 50 | import { GitCore } from "./git/Services/GitCore.ts"; | 50 | import { GitCore } from "./git/Services/GitCore.ts"; |
| 51 | import { GitCommandError, GitManagerError } from "./git/Errors.ts"; | 51 | import { GitCommandError, GitManagerError } from "./git/Errors.ts"; |
| 52 | import { MigrationError } from "@effect/sql-sqlite-bun/SqliteMigrator"; | 52 | import { MigrationError } from "@effect/sql-sqlite-bun/SqliteMigrator"; |
| 53 | import { AnalyticsServiceLayerLive } from "./telemetry/Layers/AnalyticsService.ts"; | 53 | import { AnalyticsService } from "./telemetry/Services/AnalyticsService.ts"; |
| 54 | import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient"; | ||
| 55 | 54 | ||
| 56 | interface PendingMessages { | 55 | interface PendingMessages { |
| 57 | queue: unknown[]; | 56 | queue: unknown[]; |
| ... | @@ -436,6 +435,7 @@ describe("WebSocket Server", () => { | ... | @@ -436,6 +435,7 @@ describe("WebSocket Server", () => { |
| 436 | ? Layer.succeed(TerminalManager, options.terminalManager) | 435 | ? Layer.succeed(TerminalManager, options.terminalManager) |
| 437 | : Layer.empty, | 436 | : Layer.empty, |
| 438 | ); | 437 | ); |
| 438 | |||
| 439 | const runtimeLayer = Layer.merge( | 439 | const runtimeLayer = Layer.merge( |
| 440 | Layer.merge( | 440 | Layer.merge( |
| 441 | makeServerRuntimeServicesLayer().pipe(Layer.provide(infrastructureLayer)), | 441 | makeServerRuntimeServicesLayer().pipe(Layer.provide(infrastructureLayer)), |
| ... | @@ -448,9 +448,8 @@ describe("WebSocket Server", () => { | ... | @@ -448,9 +448,8 @@ describe("WebSocket Server", () => { |
| 448 | Layer.provideMerge(providerHealthLayer), | 448 | Layer.provideMerge(providerHealthLayer), |
| 449 | Layer.provideMerge(openLayer), | 449 | Layer.provideMerge(openLayer), |
| 450 | Layer.provideMerge(serverConfigLayer), | 450 | Layer.provideMerge(serverConfigLayer), |
| 451 | Layer.provideMerge(AnalyticsServiceLayerLive), | 451 | Layer.provideMerge(AnalyticsService.layerTest), |
| 452 | Layer.provideMerge(NodeServices.layer), | 452 | Layer.provideMerge(NodeServices.layer), |
| 453 | Layer.provideMerge(NodeHttpClient.layerUndici), | ||
| 454 | ); | 453 | ); |
| 455 | const runtimeServices = await Effect.runPromise( | 454 | const runtimeServices = await Effect.runPromise( |
| 456 | Layer.build(dependenciesLayer).pipe(Scope.provide(scope)), | 455 | Layer.build(dependenciesLayer).pipe(Scope.provide(scope)), |