{"version":3,"sources":["../src/reflection-v2.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport WebSocket from 'ws';\nimport { StatusCodes, type Status } from './action.mjs';\nimport { GENKIT_REFLECTION_API_SPEC_VERSION, GENKIT_VERSION } from './index.mjs';\nimport { logger } from './logging.mjs';\nimport {\n  ReflectionCancelActionParamsSchema,\n  ReflectionConfigureParamsSchema,\n  ReflectionListActionsResponse,\n  ReflectionListValuesParamsSchema,\n  ReflectionListValuesResponseSchema,\n  ReflectionRegisterParams,\n  ReflectionRunActionParamsSchema,\n  ReflectionRunActionStateParamsSchema,\n  ReflectionStreamChunkParamsSchema,\n} from './reflection-types.mjs';\nimport type { Registry } from './registry.mjs';\nimport { toJsonSchema } from './schema.mjs';\nimport { flushTracing, setTelemetryServerUrl } from './tracing.mjs';\n\nlet apiIndex = 0;\n\ninterface JsonRpcRequest {\n  jsonrpc: '2.0';\n  method: string;\n  params?: any;\n  id?: string;\n}\n\ninterface JsonRpcResponse {\n  jsonrpc: '2.0';\n  result?: any;\n  error?: {\n    code: number;\n    message: string;\n    data?: any;\n  };\n  id: string;\n}\n\ntype JsonRpcMessage = JsonRpcRequest | JsonRpcResponse;\n\nexport interface ReflectionServerV2Options {\n  configuredEnvs?: string[];\n  name?: string;\n  url: string;\n}\n\nexport class ReflectionServerV2 {\n  private registry: Registry;\n  private options: ReflectionServerV2Options;\n  private ws: WebSocket | null = null;\n  private url: string;\n  private index = apiIndex++;\n  private activeActions = new Map<\n    string,\n    {\n      abortController: AbortController;\n      startTime: Date;\n    }\n  >();\n  private reconnectCount = 0;\n  private isStopped = false;\n  private reconnectTimeout: NodeJS.Timeout | null = null;\n  private baseDelayMs = 500;\n  private maxDelayMs = 5000;\n  private pendingRequests = new Map<\n    string,\n    {\n      resolve: (value: any) => void;\n      reject: (reason?: any) => void;\n    }\n  >();\n  private requestIdCounter = 0;\n\n  constructor(registry: Registry, options: ReflectionServerV2Options) {\n    this.registry = registry;\n    this.options = {\n      configuredEnvs: ['dev'],\n      ...options,\n    };\n    // The URL should be provided via environment variable by the CLI manager\n    this.url = this.options.url;\n  }\n\n  async start() {\n    this.isStopped = false;\n    this.reconnectCount = 0;\n    await this.connect();\n  }\n\n  private async connect() {\n    if (this.isStopped) return;\n\n    logger.debug(`Connecting to Reflection V2 server at ${this.url}`);\n    const ws = new WebSocket(this.url);\n    this.ws = ws;\n\n    this.ws.on('open', async () => {\n      logger.debug('Connected to Reflection V2 server.');\n      this.reconnectCount = 0;\n      await this.register();\n    });\n\n    this.ws.on('message', async (data) => {\n      try {\n        const message = JSON.parse(data.toString()) as any;\n        if ('method' in message) {\n          await this.handleRequest(message);\n        } else if ('id' in message) {\n          this.handleResponse(message);\n        }\n      } catch (error) {\n        logger.error(`Failed to parse message: ${error}`);\n      }\n    });\n\n    this.ws.on('error', (error) => {\n      logger.error(`Reflection V2 WebSocket error: ${error}`);\n    });\n\n    this.ws.on('close', (code, reason) => {\n      logger.debug(\n        `Reflection V2 WebSocket closed. Code: ${code}, Reason: ${reason}`\n      );\n      for (const [id, resolver] of this.pendingRequests.entries()) {\n        resolver.reject(\n          new Error(\n            `Connection closed before response was received (id: ${id})`\n          )\n        );\n      }\n      this.pendingRequests.clear();\n\n      if (!this.isStopped) {\n        this.scheduleReconnect();\n      }\n    });\n  }\n\n  private scheduleReconnect() {\n    if (this.reconnectTimeout) return;\n\n    const delay = Math.min(\n      this.baseDelayMs * Math.pow(2, this.reconnectCount),\n      this.maxDelayMs\n    );\n    this.reconnectCount++;\n\n    logger.debug(\n      `Scheduling reconnection in ${delay}ms (attempt ${this.reconnectCount})`\n    );\n\n    this.reconnectTimeout = setTimeout(async () => {\n      this.reconnectTimeout = null;\n      await this.connect();\n    }, delay);\n  }\n\n  async stop() {\n    this.isStopped = true;\n    if (this.reconnectTimeout) {\n      clearTimeout(this.reconnectTimeout);\n      this.reconnectTimeout = null;\n    }\n    if (this.ws) {\n      this.ws.close();\n      this.ws = null;\n    }\n  }\n\n  private send(message: JsonRpcMessage) {\n    if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n      this.ws.send(JSON.stringify(message));\n    }\n  }\n\n  private sendResponse(id: string, result: any) {\n    this.send({\n      jsonrpc: '2.0',\n      result,\n      id,\n    });\n  }\n\n  private sendError(id: string, code: number, message: string, data?: any) {\n    this.send({\n      jsonrpc: '2.0',\n      error: { code, message, data },\n      id,\n    });\n  }\n\n  private sendNotification(method: string, params: any) {\n    this.send({\n      jsonrpc: '2.0',\n      method,\n      params,\n    });\n  }\n\n  private sendRequest(method: string, params: any): Promise<any> {\n    return new Promise((resolve, reject) => {\n      const id = (++this.requestIdCounter).toString();\n      this.pendingRequests.set(id, { resolve, reject });\n      this.send({\n        jsonrpc: '2.0',\n        id,\n        method,\n        params,\n      });\n    });\n  }\n\n  private async register() {\n    const params: ReflectionRegisterParams = {\n      id: process.env.GENKIT_RUNTIME_ID || this.runtimeId,\n      pid: process.pid,\n      name: this.options.name || this.runtimeId,\n      genkitVersion: GENKIT_VERSION,\n      reflectionApiSpecVersion: GENKIT_REFLECTION_API_SPEC_VERSION,\n      envs: this.options.configuredEnvs,\n    };\n    try {\n      const response = await this.sendRequest('register', params);\n      if (response && response.telemetryServerUrl) {\n        if (!process.env.GENKIT_TELEMETRY_SERVER) {\n          setTelemetryServerUrl(response.telemetryServerUrl);\n          logger.debug(\n            `Connected to telemetry server on ${response.telemetryServerUrl} via handshake`\n          );\n        }\n      }\n    } catch (err) {\n      logger.error(`Failed to register with CLI: ${err}`);\n    }\n  }\n\n  get runtimeId() {\n    return `${process.pid}${this.index ? `-${this.index}` : ''}`;\n  }\n\n  private handleResponse(response: any) {\n    const resolver = this.pendingRequests.get(response.id);\n    if (!resolver) {\n      logger.error(`Unknown response ID: ${response.id}`);\n      return;\n    }\n    this.pendingRequests.delete(response.id);\n    if ('error' in response) {\n      resolver.reject(response.error);\n    } else {\n      resolver.resolve(response.result);\n    }\n  }\n\n  private async handleRequest(request: JsonRpcRequest) {\n    try {\n      switch (request.method) {\n        case 'listActions':\n          await this.handleListActions(request);\n          break;\n        case 'listValues':\n          await this.handleListValues(request);\n          break;\n        case 'runAction':\n          await this.handleRunAction(request);\n          break;\n        case 'configure':\n          this.handleConfigure(request);\n          break;\n        case 'cancelAction':\n          await this.handleCancelAction(request);\n          break;\n        case 'sendInputStreamChunk':\n          this.handleSendInputStreamChunk(request);\n          break;\n        case 'endInputStream':\n          this.handleEndInputStream(request);\n          break;\n        default:\n          if (request.id) {\n            this.sendError(\n              request.id,\n              -32601,\n              `Method not found: ${request.method}`\n            );\n          }\n      }\n    } catch (error: any) {\n      if (request.id) {\n        this.sendError(request.id, -32000, error.message, {\n          stack: error.stack,\n        });\n      }\n    }\n  }\n\n  private async handleListActions(request: JsonRpcRequest) {\n    if (!request.id) return; // Should be a request\n    const actions = await this.registry.listResolvableActions();\n    const convertedActions: Record<string, any> = {};\n\n    Object.keys(actions).forEach((key) => {\n      const action = actions[key];\n      convertedActions[key] = {\n        key,\n        name: action.name,\n        description: action.description,\n        metadata: action.metadata,\n      };\n      if (action.inputSchema || action.inputJsonSchema) {\n        convertedActions[key].inputSchema = toJsonSchema({\n          schema: action.inputSchema,\n          jsonSchema: action.inputJsonSchema,\n        });\n      }\n      if (action.outputSchema || action.outputJsonSchema) {\n        convertedActions[key].outputSchema = toJsonSchema({\n          schema: action.outputSchema,\n          jsonSchema: action.outputJsonSchema,\n        });\n      }\n    });\n\n    this.sendResponse(request.id, <ReflectionListActionsResponse>{\n      actions: convertedActions,\n    });\n  }\n\n  private async handleListValues(request: JsonRpcRequest) {\n    if (!request.id) return;\n    const { type } = ReflectionListValuesParamsSchema.parse(request.params);\n    if (type !== 'defaultModel' && type !== 'middleware') {\n      this.sendError(\n        request.id,\n        -32602,\n        `'type' ${type} is not supported. Only 'defaultModel' and 'middleware' are supported`\n      );\n      return;\n    }\n    const values = await this.registry.listValues(type);\n    const mappedValues: Record<string, any> = {};\n    for (const [key, value] of Object.entries(values)) {\n      mappedValues[key] =\n        value &&\n        typeof value === 'object' &&\n        'toJson' in value &&\n        typeof (value as any).toJson === 'function'\n          ? (value as any).toJson()\n          : value;\n    }\n    this.sendResponse(\n      request.id,\n      ReflectionListValuesResponseSchema.parse({ values: mappedValues })\n    );\n  }\n\n  private async handleRunAction(request: JsonRpcRequest) {\n    if (!request.id) return;\n\n    const { key, input, context, telemetryLabels, stream } =\n      ReflectionRunActionParamsSchema.parse(request.params);\n    const action = await this.registry.lookupAction(key);\n\n    if (!action) {\n      this.sendError(request.id, -32602, `action ${key} not found`);\n      return;\n    }\n\n    const abortController = new AbortController();\n    let traceId: string | undefined;\n\n    try {\n      const onTraceStartCallback = ({ traceId: tid }: { traceId: string }) => {\n        traceId = tid;\n        this.activeActions.set(tid, {\n          abortController,\n          startTime: new Date(),\n        });\n        // Send early trace ID notification\n        this.sendNotification(\n          'runActionState',\n          ReflectionRunActionStateParamsSchema.parse({\n            requestId: request.id,\n            state: { traceId: tid },\n          })\n        );\n      };\n\n      if (stream) {\n        const callback = (chunk: any) => {\n          this.sendNotification(\n            'streamChunk',\n            ReflectionStreamChunkParamsSchema.parse({\n              requestId: request.id,\n              chunk,\n            })\n          );\n        };\n\n        const result = await action.run(input, {\n          context,\n          onChunk: callback,\n          telemetryLabels,\n          onTraceStart: onTraceStartCallback,\n          abortSignal: abortController.signal,\n        });\n\n        await flushTracing();\n\n        // Send final result\n        this.sendResponse(request.id, {\n          result: result.result,\n          telemetry: {\n            traceId: result.telemetry.traceId,\n          },\n        });\n      } else {\n        const result = await action.run(input, {\n          context,\n          telemetryLabels,\n          onTraceStart: onTraceStartCallback,\n          abortSignal: abortController.signal,\n        });\n        await flushTracing();\n\n        this.sendResponse(request.id, {\n          result: result.result,\n          telemetry: {\n            traceId: result.telemetry.traceId,\n          },\n        });\n      }\n    } catch (err: any) {\n      const isAbort =\n        err?.name === 'AbortError' ||\n        (typeof DOMException !== 'undefined' &&\n          err instanceof DOMException &&\n          err.name === 'AbortError');\n\n      const errorResponse: Status = {\n        code: isAbort ? StatusCodes.CANCELLED : StatusCodes.INTERNAL,\n        message: isAbort ? 'Action was cancelled' : err.message,\n        details: {\n          stack: err.stack,\n        },\n      };\n      if (err.traceId || traceId) {\n        errorResponse.details.traceId = err.traceId || traceId;\n      }\n\n      this.sendError(request.id, -32000, errorResponse.message, errorResponse);\n    } finally {\n      if (traceId) {\n        this.activeActions.delete(traceId);\n      }\n    }\n  }\n\n  private handleConfigure(request: JsonRpcRequest) {\n    const { telemetryServerUrl } = ReflectionConfigureParamsSchema.parse(\n      request.params\n    );\n    if (telemetryServerUrl && !process.env.GENKIT_TELEMETRY_SERVER) {\n      setTelemetryServerUrl(telemetryServerUrl);\n      logger.debug(`Connected to telemetry server on ${telemetryServerUrl}`);\n    }\n  }\n\n  private async handleCancelAction(request: JsonRpcRequest) {\n    if (!request.id) return;\n    const { traceId } = ReflectionCancelActionParamsSchema.parse(\n      request.params\n    );\n    const activeAction = this.activeActions.get(traceId);\n    if (activeAction) {\n      activeAction.abortController.abort();\n      this.activeActions.delete(traceId);\n      this.sendResponse(request.id, { message: 'Action cancelled' });\n    } else {\n      this.sendError(\n        request.id,\n        -32602,\n        'Action not found or already completed'\n      );\n    }\n  }\n\n  private handleSendInputStreamChunk(request: JsonRpcRequest) {\n    // ReflectionSendInputStreamChunkParamsSchema.parse(request.params);\n    throw new Error('Not implemented');\n  }\n\n  private handleEndInputStream(request: JsonRpcRequest) {\n    // ReflectionEndInputStreamParamsSchema.parse(request.params);\n    throw new Error('Not implemented');\n  }\n}\n"],"mappings":"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","names":[]}