Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions apps/marketing/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type React from "react";
import type { Metadata } from "next";
import { Nunito } from "next/font/google";
import { Analytics } from "@vercel/analytics/next";
import "./globals.css";

const nunito = Nunito({ subsets: ["latin"], variable: "--font-nunito" });
Expand Down Expand Up @@ -60,10 +59,7 @@ export default function RootLayout({
}>) {
return (
<html lang="en" className="dark">
<body className={`${nunito.variable} font-sans antialiased`}>
{children}
<Analytics />
</body>
<body className={`${nunito.variable} font-sans antialiased`}>{children}</body>
</html>
);
}
1 change: 0 additions & 1 deletion apps/marketing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"@radix-ui/react-toggle": "1.1.1",
"@radix-ui/react-toggle-group": "1.1.1",
"@radix-ui/react-tooltip": "1.1.6",
"@vercel/analytics": "1.3.1",
"autoprefixer": "^10.4.20",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import { makeProviderServiceLive } from "../src/provider/Layers/ProviderService.
import { makeCodexAdapterLive } from "../src/provider/Layers/CodexAdapter.ts";
import { CodexAdapter } from "../src/provider/Services/CodexAdapter.ts";
import { ProviderService } from "../src/provider/Services/ProviderService.ts";
import { AnalyticsService } from "../src/telemetry/Services/AnalyticsService.ts";
import { CheckpointReactorLive } from "../src/orchestration/Layers/CheckpointReactor.ts";
import { OrchestrationEngineLive } from "../src/orchestration/Layers/OrchestrationEngine.ts";
import { OrchestrationProjectionPipelineLive } from "../src/orchestration/Layers/ProjectionPipeline.ts";
Expand Down Expand Up @@ -284,12 +283,10 @@ export const makeOrchestrationIntegrationHarness = (
? makeProviderServiceLive().pipe(
Layer.provide(providerSessionDirectoryLayer),
Layer.provide(realCodexRegistry),
Layer.provide(AnalyticsService.layerTest),
)
: makeProviderServiceLive().pipe(
Layer.provide(providerSessionDirectoryLayer),
Layer.provide(fakeRegistry!),
Layer.provide(AnalyticsService.layerTest),
);

const checkpointStoreLayer = CheckpointStoreLive.pipe(Layer.provide(GitCoreLive));
Expand Down
2 changes: 0 additions & 2 deletions apps/server/integration/providerService.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
ProviderService,
type ProviderServiceShape,
} from "../src/provider/Services/ProviderService.ts";
import { AnalyticsService } from "../src/telemetry/Services/AnalyticsService.ts";
import { SqlitePersistenceMemory } from "../src/persistence/Layers/Sqlite.ts";
import { ProviderSessionRuntimeRepositoryLive } from "../src/persistence/Layers/ProviderSessionRuntime.ts";

Expand Down Expand Up @@ -60,7 +59,6 @@ const makeIntegrationFixture = Effect.gen(function* () {
const shared = Layer.mergeAll(
directoryLayer,
Layer.succeed(ProviderAdapterRegistry, registry),
AnalyticsService.layerTest,
).pipe(Layer.provide(SqlitePersistenceMemory));

const layer = makeProviderServiceLive().pipe(Layer.provide(shared));
Expand Down
43 changes: 1 addition & 42 deletions apps/server/src/main.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as Http from "node:http";
import * as NodeServices from "@effect/platform-node/NodeServices";
import { assert, it, vi } from "@effect/vitest";
import type { OrchestrationReadModel } from "@okcode/contracts";
import * as ConfigProvider from "effect/ConfigProvider";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
Expand All @@ -10,11 +9,9 @@ import { FetchHttpClient } from "effect/unstable/http";
import { beforeEach } from "vitest";
import { NetService } from "@okcode/shared/Net";

import { CliConfig, recordStartupHeartbeat, okcodeCli, type CliConfigShape } from "./main";
import { CliConfig, okcodeCli, type CliConfigShape } from "./main";
import { ServerConfig, type ServerConfigShape } from "./config";
import { Open, type OpenShape } from "./open";
import { ProjectionSnapshotQuery } from "./orchestration/Services/ProjectionSnapshotQuery";
import { AnalyticsService } from "./telemetry/Services/AnalyticsService";
import { Server, type ServerShape } from "./wsServer";

const start = vi.fn(() => undefined);
Expand Down Expand Up @@ -53,7 +50,6 @@ const testLayer = Layer.mergeAll(
openInFileManager: () => Effect.void,
revealInFileManager: () => Effect.void,
} satisfies OpenShape),
AnalyticsService.layerTest,
FetchHttpClient.layer,
NodeServices.layer,
);
Expand Down Expand Up @@ -238,43 +234,6 @@ it.layer(testLayer)("server CLI command", (it) => {
}),
);

it.effect("records a startup heartbeat with thread/project counts", () =>
Effect.gen(function* () {
const recordTelemetry = vi.fn(
(_event: string, _properties?: Readonly<Record<string, unknown>>) => Effect.void,
);
const getSnapshot = vi.fn(() =>
Effect.succeed({
snapshotSequence: 2,
projects: [{} as OrchestrationReadModel["projects"][number]],
threads: [
{} as OrchestrationReadModel["threads"][number],
{} as OrchestrationReadModel["threads"][number],
],
updatedAt: new Date(1).toISOString(),
} satisfies OrchestrationReadModel),
);

yield* recordStartupHeartbeat.pipe(
Effect.provideService(ProjectionSnapshotQuery, {
getSnapshot,
}),
Effect.provideService(AnalyticsService, {
record: recordTelemetry,
flush: Effect.void,
}),
);

assert.deepEqual(recordTelemetry.mock.calls[0], [
"server.boot.heartbeat",
{
threadCount: 2,
projectCount: 1,
},
]);
}),
);

it.effect("does not start server for invalid --mode values", () =>
Effect.gen(function* () {
yield* runCli(["--mode", "invalid"]);
Expand Down
30 changes: 0 additions & 30 deletions apps/server/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,9 @@ import { fixPath, resolveBaseDir } from "./os-jank";
import { Open } from "./open";
import * as SqlitePersistence from "./persistence/Layers/Sqlite";
import { makeServerProviderLayer, makeServerRuntimeServicesLayer } from "./serverLayers";
import { ProjectionSnapshotQuery } from "./orchestration/Services/ProjectionSnapshotQuery";
import { ProviderHealthLive } from "./provider/Layers/ProviderHealth";
import { Server } from "./wsServer";
import { ServerLoggerLive } from "./serverLogger";
import { AnalyticsServiceLayerLive } from "./telemetry/Layers/AnalyticsService";
import { AnalyticsService } from "./telemetry/Services/AnalyticsService";
import { doctorCmd } from "./doctor";

export class StartupError extends Data.TaggedError("StartupError")<{
Expand Down Expand Up @@ -199,7 +196,6 @@ const LayerLive = (input: CliInput) =>
Layer.provideMerge(ProviderHealthLive),
Layer.provideMerge(SqlitePersistence.layerConfig),
Layer.provideMerge(ServerLoggerLive),
Layer.provideMerge(AnalyticsServiceLayerLive),
Layer.provideMerge(ServerConfigLive(input)),
);

Expand All @@ -209,31 +205,6 @@ const isWildcardHost = (host: string | undefined): boolean =>
const formatHostForUrl = (host: string): string =>
host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;

export const recordStartupHeartbeat = Effect.gen(function* () {
const analytics = yield* AnalyticsService;
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;

const { threadCount, projectCount } = yield* projectionSnapshotQuery.getSnapshot().pipe(
Effect.map((snapshot) => ({
threadCount: snapshot.threads.length,
projectCount: snapshot.projects.length,
})),
Effect.catch((cause) =>
Effect.logWarning("failed to gather startup snapshot for telemetry", { cause }).pipe(
Effect.as({
threadCount: 0,
projectCount: 0,
}),
),
),
);

yield* analytics.record("server.boot.heartbeat", {
threadCount,
projectCount,
});
});

const makeServerProgram = (input: CliInput) =>
Effect.gen(function* () {
const cliConfig = yield* CliConfig;
Expand All @@ -253,7 +224,6 @@ const makeServerProgram = (input: CliInput) =>
}

yield* start;
yield* Effect.forkChild(recordStartupHeartbeat);

const localUrl = `http://localhost:${config.port}`;
const bindUrl =
Expand Down
7 changes: 0 additions & 7 deletions apps/server/src/provider/Layers/ProviderService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import {
makeSqlitePersistenceLive,
SqlitePersistenceMemory,
} from "../../persistence/Layers/Sqlite.ts";
import { AnalyticsService } from "../../telemetry/Services/AnalyticsService.ts";

const asRequestId = (value: string): ApprovalRequestId => ApprovalRequestId.makeUnsafe(value);
const asEventId = (value: string): EventId => EventId.makeUnsafe(value);
Expand Down Expand Up @@ -251,7 +250,6 @@ function makeProviderServiceLayer() {
makeProviderServiceLive().pipe(
Layer.provide(providerAdapterLayer),
Layer.provide(directoryLayer),
Layer.provideMerge(AnalyticsService.layerTest),
),
directoryLayer,

Expand Down Expand Up @@ -299,7 +297,6 @@ it.effect("ProviderServiceLive keeps persisted resumable sessions on startup", (
const providerLayer = makeProviderServiceLive().pipe(
Layer.provide(Layer.succeed(ProviderAdapterRegistry, registry)),
Layer.provide(directoryLayer),
Layer.provide(AnalyticsService.layerTest),
);

yield* Effect.gen(function* () {
Expand Down Expand Up @@ -358,7 +355,6 @@ it.effect(
const firstProviderLayer = makeProviderServiceLive().pipe(
Layer.provide(Layer.succeed(ProviderAdapterRegistry, firstRegistry)),
Layer.provide(firstDirectoryLayer),
Layer.provide(AnalyticsService.layerTest),
);
const updatedResumeCursor = {
threadId: asThreadId("thread-1"),
Expand Down Expand Up @@ -409,7 +405,6 @@ it.effect(
const secondProviderLayer = makeProviderServiceLive().pipe(
Layer.provide(Layer.succeed(ProviderAdapterRegistry, secondRegistry)),
Layer.provide(secondDirectoryLayer),
Layer.provide(AnalyticsService.layerTest),
);

secondCodex.startSession.mockClear();
Expand Down Expand Up @@ -765,7 +760,6 @@ routing.layer("ProviderServiceLive routing", (it) => {
const firstProviderLayer = makeProviderServiceLive().pipe(
Layer.provide(Layer.succeed(ProviderAdapterRegistry, firstRegistry)),
Layer.provide(firstDirectoryLayer),
Layer.provide(AnalyticsService.layerTest),
);

const initial = yield* Effect.gen(function* () {
Expand Down Expand Up @@ -797,7 +791,6 @@ routing.layer("ProviderServiceLive routing", (it) => {
const secondProviderLayer = makeProviderServiceLive().pipe(
Layer.provide(Layer.succeed(ProviderAdapterRegistry, secondRegistry)),
Layer.provide(secondDirectoryLayer),
Layer.provide(AnalyticsService.layerTest),
);

secondClaude.startSession.mockClear();
Expand Down
44 changes: 0 additions & 44 deletions apps/server/src/provider/Layers/ProviderService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import {
type ProviderRuntimeBinding,
} from "../Services/ProviderSessionDirectory.ts";
import { type EventNdjsonLogger, makeEventNdjsonLogger } from "./EventNdjsonLogger.ts";
import { AnalyticsService } from "../../telemetry/Services/AnalyticsService.ts";

export interface ProviderServiceLiveOptions {
readonly canonicalEventLogPath?: string;
Expand Down Expand Up @@ -145,7 +144,6 @@ function readPersistedCwd(

const makeProviderService = (options?: ProviderServiceLiveOptions) =>
Effect.gen(function* () {
const analytics = yield* Effect.service(AnalyticsService);
const canonicalEventLogger =
options?.canonicalEventLogger ??
(options?.canonicalEventLogPath !== undefined
Expand Down Expand Up @@ -221,11 +219,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) =>
);
if (existing) {
yield* upsertSessionBinding(existing, input.binding.threadId);
yield* analytics.record("provider.session.recovered", {
provider: existing.provider,
strategy: "adopt-existing",
hasResumeCursor: existing.resumeCursor !== undefined,
});
return { adapter, session: existing } as const;
}
}
Expand Down Expand Up @@ -258,11 +251,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) =>
}

yield* upsertSessionBinding(resumed, input.binding.threadId);
yield* analytics.record("provider.session.recovered", {
provider: resumed.provider,
strategy: "resume-thread",
hasResumeCursor: resumed.resumeCursor !== undefined,
});
return { adapter, session: resumed } as const;
});

Expand Down Expand Up @@ -331,13 +319,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) =>
modelOptions: input.modelOptions,
providerOptions: input.providerOptions,
});
yield* analytics.record("provider.session.started", {
provider: session.provider,
runtimeMode: input.runtimeMode,
hasResumeCursor: session.resumeCursor !== undefined,
hasCwd: typeof input.cwd === "string" && input.cwd.trim().length > 0,
hasModel: typeof input.model === "string" && input.model.trim().length > 0,
});

return session;
});
Expand Down Expand Up @@ -377,13 +358,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) =>
lastRuntimeEventAt: new Date().toISOString(),
},
});
yield* analytics.record("provider.turn.sent", {
provider: routed.adapter.provider,
model: input.model,
interactionMode: input.interactionMode,
attachmentCount: input.attachments.length,
hasInput: typeof input.input === "string" && input.input.trim().length > 0,
});
return turn;
});

Expand All @@ -400,9 +374,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) =>
allowRecovery: true,
});
yield* routed.adapter.interruptTurn(routed.threadId, input.turnId);
yield* analytics.record("provider.turn.interrupted", {
provider: routed.adapter.provider,
});
});

const respondToRequest: ProviderServiceShape["respondToRequest"] = (rawInput) =>
Expand All @@ -418,10 +389,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) =>
allowRecovery: true,
});
yield* routed.adapter.respondToRequest(routed.threadId, input.requestId, input.decision);
yield* analytics.record("provider.request.responded", {
provider: routed.adapter.provider,
decision: input.decision,
});
});

const respondToUserInput: ProviderServiceShape["respondToUserInput"] = (rawInput) =>
Expand Down Expand Up @@ -455,9 +422,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) =>
yield* routed.adapter.stopSession(routed.threadId);
}
yield* directory.remove(input.threadId);
yield* analytics.record("provider.session.stopped", {
provider: routed.adapter.provider,
});
});

const listSessions: ProviderServiceShape["listSessions"] = () =>
Expand Down Expand Up @@ -526,10 +490,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) =>
allowRecovery: true,
});
yield* routed.adapter.rollbackThread(routed.threadId, input.numTurns);
yield* analytics.record("provider.conversation.rolled_back", {
provider: routed.adapter.provider,
turns: input.numTurns,
});
});

const runStopAll = () =>
Expand Down Expand Up @@ -563,10 +523,6 @@ const makeProviderService = (options?: ProviderServiceLiveOptions) =>
),
),
).pipe(Effect.asVoid);
yield* analytics.record("provider.sessions.stopped_all", {
sessionCount: threadIds.length,
});
yield* analytics.flush;
});

yield* Effect.addFinalizer(() =>
Expand Down
3 changes: 1 addition & 2 deletions apps/server/src/serverLayers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import { WorkflowEngineLive } from "./prReview/Layers/WorkflowEngine";
import { MergeConflictResolverLive } from "./prReview/Layers/MergeConflictResolver";
import { PrReviewLive } from "./prReview/Layers/PrReview";
import { PtyAdapter } from "./terminal/Services/PTY";
import { AnalyticsService } from "./telemetry/Services/AnalyticsService";

type RuntimePtyAdapterLoader = {
layer: Layer.Layer<PtyAdapter, never, FileSystem.FileSystem | Path.Path>;
Expand All @@ -61,7 +60,7 @@ const makeRuntimePtyAdapterLayer = () =>
export function makeServerProviderLayer(): Layer.Layer<
ProviderService,
ProviderUnsupportedError,
SqlClient.SqlClient | ServerConfig | FileSystem.FileSystem | AnalyticsService
SqlClient.SqlClient | ServerConfig | FileSystem.FileSystem
> {
return Effect.gen(function* () {
const { providerEventLogPath } = yield* ServerConfig;
Expand Down
Loading
Loading