| 140 | } |
| 141 | |
| 142 | export class KimiCore implements PromisableMethods<CoreAPI> { |
| 143 | readonly sdk: Promise<SDKRPC>; |
| 144 | readonly homeDir: string; |
| 145 | readonly configPath: string; |
| 146 | readonly sessions = new Map<string, Session>(); |
| 147 | readonly telemetry: TelemetryClient; |
| 148 | |
| 149 | private kaos: Promise<Kaos> | undefined; |
| 150 | private runtime: ToolServices | undefined; |
| 151 | private config: KimiConfig; |
| 152 | private configWarnings: readonly string[] = []; |
| 153 | private readonly runtimeOverride: ToolServices | undefined; |
| 154 | private readonly userHomeDir: string; |
| 155 | private readonly kimiRequestHeaders: Record<string, string> | undefined; |
| 156 | private readonly resolveOAuthTokenProvider: OAuthTokenProviderResolver | undefined; |
| 157 | private readonly skillDirs: readonly string[]; |
| 158 | private readonly sessionStore: SessionStore; |
| 159 | readonly plugins: PluginManager; |
| 160 | private pluginsReady: Promise<void>; |
| 161 | private pluginsLoadError: Error | undefined; |
| 162 | private readonly appVersion: string | undefined; |
| 163 | private readonly experimentalFlags: FlagResolver; |
| 164 | |
| 165 | constructor( |
| 166 | protected readonly rpcClient: CoreRPCClient, |
| 167 | options: KimiCoreOptions = {}, |
| 168 | ) { |
| 169 | this.homeDir = resolveKimiHome(options.homeDir); |
| 170 | this.userHomeDir = homedir(); |
| 171 | this.configPath = resolveConfigPath({ |
| 172 | homeDir: this.homeDir, |
| 173 | configPath: options.configPath, |
| 174 | }); |
| 175 | this.runtimeOverride = options.runtime; |
| 176 | this.runtime = options.runtime; |
| 177 | this.kimiRequestHeaders = options.kimiRequestHeaders; |
| 178 | this.resolveOAuthTokenProvider = options.resolveOAuthTokenProvider; |
| 179 | this.skillDirs = options.skillDirs ?? []; |
| 180 | this.telemetry = options.telemetry ?? noopTelemetryClient; |
| 181 | this.appVersion = options.appVersion; |
| 182 | ensureKimiHome(this.homeDir); |
| 183 | // Schema errors degrade (invalid sections are dropped with warnings) so a |
| 184 | // typo cannot prevent startup, but a file that cannot be used at all — |
| 185 | // TOML syntax error, unreadable — fails fast: defaults-only would start |
| 186 | // the app looking logged out, which is worse than the parse error. |
| 187 | const loaded = loadRuntimeConfigSafe(this.configPath); |
| 188 | if (loaded.fileError !== undefined) { |
| 189 | throw loaded.fileError; |
| 190 | } |
| 191 | this.config = loaded.config; |
| 192 | this.configWarnings = [...loaded.fileWarnings, ...loaded.envWarnings]; |
| 193 | if (this.configWarnings.length > 0) { |
| 194 | log.warn('config load degraded', { warnings: this.configWarnings }); |
| 195 | } |
| 196 | this.experimentalFlags = new FlagResolver( |
| 197 | process.env, |
| 198 | FLAG_DEFINITIONS, |
| 199 | this.config.experimental, |
nothing calls this directly
no outgoing calls
no test coverage detected