158 lines · 6.2 KB · TypeScript
RawDownload
import { GrokSettings, ProviderDriverKind } from "@t3tools/contracts";import * as Crypto from "effect/Crypto";import * as Effect from "effect/Effect";import * as FileSystem from "effect/FileSystem";import * as Path from "effect/Path";import * as Schema from "effect/Schema";import { HttpClient } from "effect/unstable/http";import { ChildProcessSpawner } from "effect/unstable/process"; import * as BackgroundPolicy from "../../background/BackgroundPolicy.ts";import { ServerConfig } from "../../config.ts";import { ServerSettingsService } from "../../serverSettings.ts";import { makeGrokTextGeneration } from "../../textGeneration/GrokTextGeneration.ts";import { ProviderDriverError } from "../Errors.ts";import { makeGrokAdapter } from "../Layers/GrokAdapter.ts";import {  buildInitialGrokProviderSnapshot,  checkGrokProviderStatus,  enrichGrokSnapshot,} from "../Layers/GrokProvider.ts";import { ProviderEventLoggers } from "../Layers/ProviderEventLoggers.ts";import { makeManagedServerProvider } from "../makeManagedServerProvider.ts";import {  defaultProviderContinuationIdentity,  type ProviderDriver,  type ProviderInstance,} from "../ProviderDriver.ts";import { withInstanceIdentity } from "./instanceIdentity.ts";import { mergeProviderInstanceEnvironment } from "../ProviderInstanceEnvironment.ts";import { discoverGrokSkills } from "./GrokSkills.ts";import { makeManualOnlyProviderMaintenanceCapabilities } from "../providerMaintenance.ts";import {  haveProviderSnapshotSettingsChanged,  makeProviderSnapshotSettingsSource,  type ProviderSnapshotSettings,} from "../providerUpdateSettings.ts";const decodeGrokSettings = Schema.decodeSync(GrokSettings); const DRIVER_KIND = ProviderDriverKind.make("grok");const MAINTENANCE_CAPABILITIES = makeManualOnlyProviderMaintenanceCapabilities({  provider: DRIVER_KIND,  packageName: null,}); export type GrokDriverEnv =  | BackgroundPolicy.BackgroundPolicy  | ChildProcessSpawner.ChildProcessSpawner  | Crypto.Crypto  | FileSystem.FileSystem  | HttpClient.HttpClient  | Path.Path  | ProviderEventLoggers  | ServerConfig  | ServerSettingsService; export const GrokDriver: ProviderDriver<GrokSettings, GrokDriverEnv> = {  driverKind: DRIVER_KIND,  metadata: {    displayName: "Grok",    supportsMultipleInstances: true,  },  configSchema: GrokSettings,  defaultConfig: (): GrokSettings => decodeGrokSettings({}),  create: ({ instanceId, displayName, accentColor, environment, enabled, config }) =>    Effect.gen(function* () {      const crypto = yield* Crypto.Crypto;      const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;      const httpClient = yield* HttpClient.HttpClient;      const serverSettings = yield* ServerSettingsService;      const { cwd } = yield* ServerConfig;      const eventLoggers = yield* ProviderEventLoggers;      const processEnv = mergeProviderInstanceEnvironment(environment);      const continuationIdentity = defaultProviderContinuationIdentity({        driverKind: DRIVER_KIND,        instanceId,      });      const stampIdentity = withInstanceIdentity({        instanceId,        driverKind: DRIVER_KIND,        displayName,        accentColor,        continuationGroupKey: continuationIdentity.continuationKey,      });      const effectiveConfig = { ...config, enabled } satisfies GrokSettings;      const adapter = yield* makeGrokAdapter(effectiveConfig, {        environment: processEnv,        ...(eventLoggers.native ? { nativeEventLogger: eventLoggers.native } : {}),        instanceId,      });      const textGeneration = yield* makeGrokTextGeneration(effectiveConfig, processEnv);       const checkProvider = checkGrokProviderStatus(effectiveConfig, processEnv, cwd).pipe(        Effect.map(stampIdentity),        Effect.provideService(Crypto.Crypto, crypto),        Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner),      );       const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, serverSettings);      const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<GrokSettings>>({        resolveMaintenance: () => Effect.succeed(MAINTENANCE_CAPABILITIES),        getSettings: snapshotSettings.getSettings,        streamSettings: snapshotSettings.streamSettings,        haveSettingsChanged: haveProviderSnapshotSettingsChanged,        initialSnapshot: (settings) =>          buildInitialGrokProviderSnapshot(settings.provider).pipe(Effect.map(stampIdentity)),        checkProvider,        enrichSnapshot: ({ settings, snapshot: currentSnapshot, publishSnapshot }) =>          enrichGrokSnapshot({            snapshot: currentSnapshot,            maintenanceCapabilities: MAINTENANCE_CAPABILITIES,            enableProviderUpdateChecks: settings.enableProviderUpdateChecks,            publishSnapshot,            httpClient,          }),      }).pipe(        Effect.mapError(          (cause) =>            new ProviderDriverError({              driver: DRIVER_KIND,              instanceId,              detail: `Failed to build Grok snapshot: ${cause.message ?? String(cause)}`,              cause,            }),        ),      );      const snapshotForCwd = (workspaceCwd: string) =>        !effectiveConfig.enabled          ? snapshot.getSnapshot          : Effect.all([              snapshot.getSnapshot,              discoverGrokSkills(effectiveConfig, processEnv, workspaceCwd).pipe(                Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner),                Effect.mapError(                  (cause) =>                    new ProviderDriverError({                      driver: DRIVER_KIND,                      instanceId,                      detail: `Failed to discover Grok skills for '${workspaceCwd}'`,                      cause,                    }),                ),              ),            ]).pipe(Effect.map(([machineSnapshot, skills]) => ({ ...machineSnapshot, skills })));       return {        instanceId,        driverKind: DRIVER_KIND,        continuationIdentity,        displayName,        accentColor,        enabled,        snapshot,        snapshotForCwd,        adapter,        textGeneration,      } satisfies ProviderInstance;    }),};