@plolink/sdk 0.0.5 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +40 -26
  2. package/dist/{chunk-4H4RACSE.js → chunk-LHNCGCWW.js} +137 -3
  3. package/dist/chunk-LHNCGCWW.js.map +1 -0
  4. package/dist/{chunk-NS3DJP2O.cjs → chunk-WFBN23AH.cjs} +141 -2
  5. package/dist/chunk-WFBN23AH.cjs.map +1 -0
  6. package/dist/client-DXKAtLg1.d.ts +848 -0
  7. package/dist/client-l6cekf09.d.cts +848 -0
  8. package/dist/common/index.cjs +18 -14
  9. package/dist/common/index.d.cts +126 -1
  10. package/dist/common/index.d.ts +126 -1
  11. package/dist/common/index.js +1 -1
  12. package/dist/index.cjs +751 -13
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +410 -3
  15. package/dist/index.d.ts +410 -3
  16. package/dist/index.js +735 -3
  17. package/dist/index.js.map +1 -1
  18. package/dist/modules/billing/index.cjs +1 -1
  19. package/dist/modules/billing/index.d.cts +1 -1
  20. package/dist/modules/billing/index.d.ts +1 -1
  21. package/dist/modules/billing/index.js +1 -1
  22. package/dist/modules/rbac/index.d.cts +1 -1
  23. package/dist/modules/rbac/index.d.ts +1 -1
  24. package/dist/modules/team/index.d.cts +1 -1
  25. package/dist/modules/team/index.d.ts +1 -1
  26. package/dist/modules/video-psych-analysis/index.cjs +123 -4
  27. package/dist/modules/video-psych-analysis/index.cjs.map +1 -1
  28. package/dist/modules/video-psych-analysis/index.d.cts +231 -93
  29. package/dist/modules/video-psych-analysis/index.d.ts +231 -93
  30. package/dist/modules/video-psych-analysis/index.js +123 -4
  31. package/dist/modules/video-psych-analysis/index.js.map +1 -1
  32. package/dist/modules/virtual-account/index.d.cts +1 -1
  33. package/dist/modules/virtual-account/index.d.ts +1 -1
  34. package/package.json +1 -16
  35. package/dist/chunk-4H4RACSE.js.map +0 -1
  36. package/dist/chunk-NS3DJP2O.cjs.map +0 -1
  37. package/dist/client-CAjIQKPm.d.cts +0 -193
  38. package/dist/client-CwNikk7i.d.ts +0 -193
  39. package/dist/modules/agent/index.cjs +0 -21
  40. package/dist/modules/agent/index.cjs.map +0 -1
  41. package/dist/modules/agent/index.d.cts +0 -71
  42. package/dist/modules/agent/index.d.ts +0 -71
  43. package/dist/modules/agent/index.js +0 -19
  44. package/dist/modules/agent/index.js.map +0 -1
  45. package/dist/modules/chat/index.cjs +0 -20
  46. package/dist/modules/chat/index.cjs.map +0 -1
  47. package/dist/modules/chat/index.d.cts +0 -68
  48. package/dist/modules/chat/index.d.ts +0 -68
  49. package/dist/modules/chat/index.js +0 -18
  50. package/dist/modules/chat/index.js.map +0 -1
  51. package/dist/modules/psych/index.cjs +0 -20
  52. package/dist/modules/psych/index.cjs.map +0 -1
  53. package/dist/modules/psych/index.d.cts +0 -69
  54. package/dist/modules/psych/index.d.ts +0 -69
  55. package/dist/modules/psych/index.js +0 -18
  56. package/dist/modules/psych/index.js.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/logger.ts","../src/core/request.ts","../src/core/client.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { LogLevel, LoggerFunction } from '../types';\n\n/**\n * SDK 内部日志器\n * \n * @description\n * 提供统一的日志接口,支持用户自定义日志钩子。\n * 默认使用 console 输出,用户可以通过配置自定义 logger 函数来集成 Sentry 等监控系统。\n * \n * @example\n * ```typescript\n * const logger = new InternalLogger((level, message, data) => {\n * // 自定义日志处理,例如发送到 Sentry\n * console.log(`[${level}] ${message}`, data);\n * });\n * \n * logger.info('Operation started', { userId: '123' });\n * logger.error('Operation failed', { error: 'Network timeout' });\n * ```\n */\nexport class InternalLogger {\n /**\n * 用户自定义的日志钩子函数\n */\n private readonly userLogger?: LoggerFunction;\n\n /**\n * 是否启用日志输出\n * 可以通过环境变量 PLOLINK_SDK_DEBUG 控制\n */\n private readonly isDebugEnabled: boolean;\n\n /**\n * 创建一个 InternalLogger 实例\n * \n * @param userLogger - 用户自定义的日志钩子函数\n */\n constructor(userLogger?: LoggerFunction) {\n this.userLogger = userLogger;\n this.isDebugEnabled =\n typeof process !== 'undefined' &&\n process.env?.PLOLINK_SDK_DEBUG === 'true';\n }\n\n /**\n * 记录信息级别日志\n * \n * @param message - 日志消息\n * @param context - 附加上下文数据\n */\n public info(message: string, context?: unknown): void {\n this.log('info', message, context);\n }\n\n /**\n * 记录警告级别日志\n * \n * @param message - 日志消息\n * @param context - 附加上下文数据\n */\n public warn(message: string, context?: unknown): void {\n this.log('warn', message, context);\n }\n\n /**\n * 记录错误级别日志\n * \n * @param message - 日志消息\n * @param context - 附加上下文数据\n */\n public error(message: string, context?: unknown): void {\n this.log('error', message, context);\n }\n\n /**\n * 记录调试级别日志\n * 只有在 debug 模式下才会输出\n * \n * @param message - 日志消息\n * @param context - 附加上下文数据\n */\n public debug(message: string, context?: unknown): void {\n if (this.isDebugEnabled) {\n this.log('debug', message, context);\n }\n }\n\n /**\n * 内部日志记录方法\n * \n * @param level - 日志级别\n * @param message - 日志消息\n * @param context - 附加上下文数据\n */\n private log(level: LogLevel, message: string, context?: unknown): void {\n const formattedMessage = `[Plolink SDK] ${message}`;\n\n // 优先使用用户自定义的 logger\n if (this.userLogger) {\n this.userLogger(level, formattedMessage, context);\n return;\n }\n\n // 降级到 console 输出\n const logData = context ? [formattedMessage, context] : [formattedMessage];\n\n switch (level) {\n case 'info':\n case 'debug':\n // eslint-disable-next-line no-console\n console.log(...logData);\n break;\n case 'warn':\n console.warn(...logData);\n break;\n case 'error':\n console.error(...logData);\n break;\n }\n }\n\n /**\n * 创建一个带有固定上下文的子 logger\n * \n * @param context - 固定的上下文数据\n * @returns 新的 logger 实例\n * \n * @example\n * ```typescript\n * const logger = new InternalLogger();\n * const moduleLogger = logger.withContext({ module: 'billing' });\n * moduleLogger.info('Payment processed'); // 日志会自动带上 module: 'billing'\n * ```\n */\n public withContext(context: Record<string, unknown>): InternalLogger {\n const parentLogger = this.userLogger;\n const wrappedLogger: LoggerFunction = (level, message, data) => {\n const mergedData = { ...context, ...((data as Record<string, unknown>) || {}) };\n if (parentLogger) {\n parentLogger(level, message, mergedData);\n } else {\n // 使用默认的 console 输出\n const formattedMessage = `[Plolink SDK] ${message}`;\n const logData = [formattedMessage, mergedData];\n switch (level) {\n case 'info':\n case 'debug':\n // eslint-disable-next-line no-console\n console.log(...logData);\n break;\n case 'warn':\n console.warn(...logData);\n break;\n case 'error':\n console.error(...logData);\n break;\n }\n }\n };\n\n return new InternalLogger(wrappedLogger);\n }\n}\n\n","import axios, { type AxiosInstance, type AxiosRequestConfig, AxiosError } from 'axios';\nimport { PlolinkError } from './error';\nimport { InternalLogger } from './logger';\nimport type { SDKConfig } from '../types';\n\n/**\n * 标准 API 响应格式\n */\ninterface APIResponse<T = unknown> {\n code: number;\n message: string;\n data: T;\n}\n\n/**\n * 创建配置好的 Axios 实例\n * \n * @description\n * 创建一个单例的 Axios 实例,配置了请求和响应拦截器。\n * - 请求拦截器:注入 Bearer Token 认证\n * - 响应拦截器:统一处理 code/message/data 格式,只返回 data 部分\n * - 错误处理:将所有错误转换为 PlolinkError\n * \n * @param config - SDK 配置对象\n * @param logger - 日志记录器\n * @returns 配置好的 Axios 实例\n * \n * @internal\n */\nexport function createAxiosInstance(\n config: Required<SDKConfig>,\n logger: InternalLogger\n): AxiosInstance {\n // 创建 Axios 实例\n const instance = axios.create({\n baseURL: config.baseUrl,\n timeout: config.timeout,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n // 请求拦截器:注入认证信息\n instance.interceptors.request.use(\n (requestConfig) => {\n const method = requestConfig.method?.toUpperCase() || 'GET';\n const url = requestConfig.url || '';\n\n logger.debug(`Request: ${method} ${url}`, {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n params: requestConfig.params,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n data: requestConfig.data,\n });\n\n // 统一使用 Bearer Token 认证\n if (config.token) {\n requestConfig.headers = requestConfig.headers || {};\n requestConfig.headers['Authorization'] = `Bearer ${config.token}`;\n }\n\n return requestConfig;\n },\n (error: AxiosError) => {\n logger.error('Request interceptor error', { error: error.message });\n return Promise.reject(error);\n }\n );\n\n // 响应拦截器:统一格式化与状态检测\n instance.interceptors.response.use(\n (response) => {\n const { code, data, message } = response.data as APIResponse;\n\n logger.debug(`Response: ${response.config.method?.toUpperCase()} ${response.config.url}`, {\n code,\n message,\n });\n\n // 检查业务状态码(根据后端约定,200 或 0 表示成功)\n if (code !== 200 && code !== 0) {\n const error = new PlolinkError(\n message || 'Unknown business error',\n code,\n data\n );\n logger.error('Business error', {\n code,\n message,\n data,\n });\n throw error;\n }\n\n // 直接返回 data 部分\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n return data as unknown as typeof response;\n },\n (error: AxiosError) => {\n // 处理网络错误和 HTTP 错误\n const status = error.response?.status || 'NETWORK_ERROR';\n const message =\n (error.response?.data as APIResponse)?.message ||\n error.message ||\n 'Network request failed';\n const data = (error.response?.data as APIResponse)?.data;\n\n logger.error('Response error', {\n status,\n message,\n url: error.config?.url,\n method: error.config?.method,\n });\n\n throw new PlolinkError(message, status, data);\n }\n );\n\n return instance;\n}\n\n/**\n * 为 Axios 实例添加类型安全的请求方法\n * \n * @description\n * 这些方法封装了 Axios 的原始方法,提供更好的类型推断。\n */\nexport interface TypedAxiosInstance extends AxiosInstance {\n get<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;\n post<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;\n put<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;\n patch<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;\n delete<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;\n}\n\n","import type { SDKConfig } from '../types';\nimport { InternalLogger } from './logger';\nimport { createAxiosInstance, type TypedAxiosInstance } from './request';\nimport { PlolinkError } from './error';\n\n/**\n * Plolink SDK 客户端主类\n * \n * @description\n * PlolinkClient 是 SDK 的核心类,负责:\n * - 管理 SDK 配置(认证 Token、API 地址等)\n * - 初始化 Axios 实例并配置拦截器\n * - 提供统一的日志接口\n * - 作为所有业务模块的基础依赖\n * \n * @example\n * ```typescript\n * // 使用 ApiKey\n * const client = new PlolinkClient({\n * token: 'sk-123456789',\n * logger: (level, msg, data) => {\n * console.log(`[${level}] ${msg}`, data);\n * }\n * });\n * \n * // 使用 SessionId (登录后获取)\n * const client = new PlolinkClient({\n * token: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',\n * baseUrl: 'https://api.plolink.com'\n * });\n * ```\n */\nexport class PlolinkClient {\n /**\n * SDK 配置对象(已填充默认值)\n */\n public readonly config: Required<SDKConfig>;\n\n /**\n * Axios 实例,用于发起 HTTP 请求\n */\n public readonly axiosInstance: TypedAxiosInstance;\n\n /**\n * 内部日志记录器\n */\n public readonly logger: InternalLogger;\n\n /**\n * 创建一个 PlolinkClient 实例\n * \n * @param config - SDK 配置对象\n * @throws {PlolinkError} 当配置验证失败时抛出\n * \n * @example\n * ```typescript\n * const client = new PlolinkClient({\n * token: 'sk-your-api-key'\n * });\n * ```\n */\n constructor(config: SDKConfig) {\n // 验证配置\n this.validateConfig(config);\n\n // 填充默认配置\n this.config = {\n baseUrl: config.baseUrl || 'https://hiring.djangotech.com/',\n token: config.token,\n timeout: config.timeout || 10000,\n logger: config.logger || (() => {}),\n };\n\n // 初始化日志记录器\n this.logger = new InternalLogger(this.config.logger);\n\n this.logger.info('Initializing Plolink SDK Client', {\n baseUrl: this.config.baseUrl,\n timeout: this.config.timeout,\n hasToken: !!this.config.token,\n });\n\n // 创建 Axios 实例\n this.axiosInstance = createAxiosInstance(\n this.config,\n this.logger\n ) as TypedAxiosInstance;\n }\n\n /**\n * 验证 SDK 配置\n * \n * @param config - SDK 配置对象\n * @throws {PlolinkError} 当配置不合法时抛出\n * @private\n */\n private validateConfig(config: SDKConfig): void {\n // 验证必填字段 token\n if (!config.token) {\n throw new PlolinkError(\n 'Config validation failed: token is required',\n 'CONFIG_ERROR'\n );\n }\n\n // 验证 token 格式(ApiKey 或 SessionId)\n const isApiKey = config.token.startsWith('sk-');\n const isSessionId = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(config.token);\n \n if (!isApiKey && !isSessionId) {\n throw new PlolinkError(\n 'Config validation failed: token must be either an ApiKey (sk-xxx) or a SessionId (UUID format)',\n 'CONFIG_ERROR'\n );\n }\n\n // 验证 baseUrl 格式\n if (config.baseUrl) {\n try {\n new URL(config.baseUrl);\n } catch {\n throw new PlolinkError(\n `Config validation failed: baseUrl is not a valid URL: ${config.baseUrl}`,\n 'CONFIG_ERROR'\n );\n }\n }\n\n // 验证 timeout\n if (config.timeout !== undefined && (config.timeout <= 0 || !Number.isFinite(config.timeout))) {\n throw new PlolinkError(\n `Config validation failed: timeout must be a positive number, got ${config.timeout}`,\n 'CONFIG_ERROR'\n );\n }\n }\n\n /**\n * 获取当前 SDK 版本\n * \n * @returns SDK 版本号\n */\n public getVersion(): string {\n return '1.0.0';\n }\n\n /**\n * 检查客户端健康状态\n * \n * @returns 健康状态信息\n * \n * @example\n * ```typescript\n * const health = client.healthCheck();\n * console.log(health);\n * // { status: 'ok', baseUrl: '...', version: '...' }\n * ```\n */\n public healthCheck(): {\n status: 'ok';\n baseUrl: string;\n version: string;\n hasToken: boolean;\n } {\n return {\n status: 'ok',\n baseUrl: this.config.baseUrl,\n version: this.getVersion(),\n hasToken: !!this.config.token,\n };\n }\n}\n\n","/**\n * Plolink SDK 主入口\n * \n * @description\n * Plolink 开放平台官方 SDK,提供完整的 API 调用能力。\n * \n * @packageDocumentation\n * \n * @example\n * ```typescript\n * import { PlolinkClient } from '@plolink/sdk';\n * \n * // 创建客户端实例\n * const client = new PlolinkClient({\n * token: 'sk-your-api-key',\n * logger: (level, message, data) => {\n * console.log(`[${level}] ${message}`, data);\n * }\n * });\n * \n * // 检查健康状态\n * const health = client.healthCheck();\n * console.log(health);\n * ```\n */\n\n// 导出核心类\nexport { PlolinkClient } from './core/client';\nexport { PlolinkError } from './core/error';\nexport { InternalLogger } from './core/logger';\n\n// 导出公共工具(供高级用户使用)\nexport { Poller } from './common/poller';\nexport { EventEmitter, TypedEventEmitter } from './common/hooks';\nexport {\n isNode,\n isBrowser,\n isWebWorker,\n getEnvironment,\n environmentInfo,\n} from './common/adapter';\n\n// 导出类型定义\nexport type {\n SDKConfig,\n LogLevel,\n LoggerFunction,\n PollerOptions,\n PollerSnapshot,\n // shared (跨模块通用类型)\n RoleType,\n ScopeType,\n AssignRoleParams,\n} from './types';\n\n// 导出版本信息\nexport const VERSION = '1.0.0';\n\n/**\n * SDK 默认配置\n */\nexport const DEFAULT_CONFIG = {\n baseUrl: 'https://hiring.djangotech.com/',\n timeout: 10000,\n initialInterval: 1000,\n maxInterval: 30000,\n backoffFactor: 1.5,\n} as const;\n\n"]}
1
+ {"version":3,"sources":["../src/core/logger.ts","../src/core/request.ts","../src/modules/psychology-test/index.ts","../src/core/client.ts","../src/modules/info-sync/index.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { LogLevel, LoggerFunction } from '../types';\n\n/**\n * SDK 内部日志器\n * \n * @description\n * 提供统一的日志接口,支持用户自定义日志钩子。\n * 默认使用 console 输出,用户可以通过配置自定义 logger 函数来集成 Sentry 等监控系统。\n * \n * @example\n * ```typescript\n * const logger = new InternalLogger((level, message, data) => {\n * // 自定义日志处理,例如发送到 Sentry\n * console.log(`[${level}] ${message}`, data);\n * });\n * \n * logger.info('Operation started', { userId: '123' });\n * logger.error('Operation failed', { error: 'Network timeout' });\n * ```\n */\nexport class InternalLogger {\n /**\n * 用户自定义的日志钩子函数\n */\n private readonly userLogger?: LoggerFunction;\n\n /**\n * 是否启用日志输出\n * 可以通过环境变量 PLOLINK_SDK_DEBUG 控制\n */\n private readonly isDebugEnabled: boolean;\n\n /**\n * 创建一个 InternalLogger 实例\n * \n * @param userLogger - 用户自定义的日志钩子函数\n */\n constructor(userLogger?: LoggerFunction) {\n this.userLogger = userLogger;\n this.isDebugEnabled =\n typeof process !== 'undefined' &&\n process.env?.PLOLINK_SDK_DEBUG === 'true';\n }\n\n /**\n * 记录信息级别日志\n * \n * @param message - 日志消息\n * @param context - 附加上下文数据\n */\n public info(message: string, context?: unknown): void {\n this.log('info', message, context);\n }\n\n /**\n * 记录警告级别日志\n * \n * @param message - 日志消息\n * @param context - 附加上下文数据\n */\n public warn(message: string, context?: unknown): void {\n this.log('warn', message, context);\n }\n\n /**\n * 记录错误级别日志\n * \n * @param message - 日志消息\n * @param context - 附加上下文数据\n */\n public error(message: string, context?: unknown): void {\n this.log('error', message, context);\n }\n\n /**\n * 记录调试级别日志\n * 只有在 debug 模式下才会输出\n * \n * @param message - 日志消息\n * @param context - 附加上下文数据\n */\n public debug(message: string, context?: unknown): void {\n if (this.isDebugEnabled) {\n this.log('debug', message, context);\n }\n }\n\n /**\n * 内部日志记录方法\n * \n * @param level - 日志级别\n * @param message - 日志消息\n * @param context - 附加上下文数据\n */\n private log(level: LogLevel, message: string, context?: unknown): void {\n const formattedMessage = `[Plolink SDK] ${message}`;\n\n // 优先使用用户自定义的 logger\n if (this.userLogger) {\n this.userLogger(level, formattedMessage, context);\n return;\n }\n\n // 降级到 console 输出\n const logData = context ? [formattedMessage, context] : [formattedMessage];\n\n switch (level) {\n case 'info':\n case 'debug':\n // eslint-disable-next-line no-console\n console.log(...logData);\n break;\n case 'warn':\n console.warn(...logData);\n break;\n case 'error':\n console.error(...logData);\n break;\n }\n }\n\n /**\n * 创建一个带有固定上下文的子 logger\n * \n * @param context - 固定的上下文数据\n * @returns 新的 logger 实例\n * \n * @example\n * ```typescript\n * const logger = new InternalLogger();\n * const moduleLogger = logger.withContext({ module: 'billing' });\n * moduleLogger.info('Payment processed'); // 日志会自动带上 module: 'billing'\n * ```\n */\n public withContext(context: Record<string, unknown>): InternalLogger {\n const parentLogger = this.userLogger;\n const wrappedLogger: LoggerFunction = (level, message, data) => {\n const mergedData = { ...context, ...((data as Record<string, unknown>) || {}) };\n if (parentLogger) {\n parentLogger(level, message, mergedData);\n } else {\n // 使用默认的 console 输出\n const formattedMessage = `[Plolink SDK] ${message}`;\n const logData = [formattedMessage, mergedData];\n switch (level) {\n case 'info':\n case 'debug':\n // eslint-disable-next-line no-console\n console.log(...logData);\n break;\n case 'warn':\n console.warn(...logData);\n break;\n case 'error':\n console.error(...logData);\n break;\n }\n }\n };\n\n return new InternalLogger(wrappedLogger);\n }\n}\n\n","import axios, { type AxiosInstance, type AxiosRequestConfig, AxiosError } from 'axios';\nimport { PlolinkError } from './error';\nimport { InternalLogger } from './logger';\nimport type { SDKConfig } from '../types';\n\n/**\n * 标准 API 响应格式\n */\ninterface APIResponse<T = unknown> {\n code: number;\n message: string;\n data: T;\n}\n\n/**\n * 创建配置好的 Axios 实例\n * \n * @description\n * 创建一个单例的 Axios 实例,配置了请求和响应拦截器。\n * - 请求拦截器:注入 Bearer Token 认证\n * - 响应拦截器:统一处理 code/message/data 格式,只返回 data 部分\n * - 错误处理:将所有错误转换为 PlolinkError\n * \n * @param config - SDK 配置对象\n * @param logger - 日志记录器\n * @returns 配置好的 Axios 实例\n * \n * @internal\n */\nexport function createAxiosInstance(\n config: Required<SDKConfig>,\n logger: InternalLogger\n): AxiosInstance {\n // 创建 Axios 实例\n const instance = axios.create({\n baseURL: config.baseUrl,\n timeout: config.timeout,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n // 请求拦截器:注入认证信息\n instance.interceptors.request.use(\n (requestConfig) => {\n const method = requestConfig.method?.toUpperCase() || 'GET';\n const url = requestConfig.url || '';\n\n logger.debug(`Request: ${method} ${url}`, {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n params: requestConfig.params,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n data: requestConfig.data,\n });\n\n // 统一使用 Bearer Token 认证\n if (config.token) {\n requestConfig.headers = requestConfig.headers || {};\n requestConfig.headers['Authorization'] = `Bearer ${config.token}`;\n }\n\n return requestConfig;\n },\n (error: AxiosError) => {\n logger.error('Request interceptor error', { error: error.message });\n return Promise.reject(error);\n }\n );\n\n // 响应拦截器:统一格式化与状态检测\n instance.interceptors.response.use(\n (response) => {\n const { code, data, message } = response.data as APIResponse;\n\n logger.debug(`Response: ${response.config.method?.toUpperCase()} ${response.config.url}`, {\n code,\n message,\n });\n\n // 检查业务状态码(根据后端约定,200 或 0 表示成功)\n if (code !== 200 && code !== 0) {\n const error = new PlolinkError(\n message || 'Unknown business error',\n code,\n data\n );\n logger.error('Business error', {\n code,\n message,\n data,\n });\n throw error;\n }\n\n // 直接返回 data 部分\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n return data as unknown as typeof response;\n },\n (error: AxiosError) => {\n // 处理网络错误和 HTTP 错误\n const status = error.response?.status || 'NETWORK_ERROR';\n const message =\n (error.response?.data as APIResponse)?.message ||\n error.message ||\n 'Network request failed';\n const data = (error.response?.data as APIResponse)?.data;\n\n logger.error('Response error', {\n status,\n message,\n url: error.config?.url,\n method: error.config?.method,\n });\n\n throw new PlolinkError(message, status, data);\n }\n );\n\n return instance;\n}\n\n/**\n * 为 Axios 实例添加类型安全的请求方法\n * \n * @description\n * 这些方法封装了 Axios 的原始方法,提供更好的类型推断。\n */\nexport interface TypedAxiosInstance extends AxiosInstance {\n get<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;\n post<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;\n put<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;\n patch<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;\n delete<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;\n}\n\n","/**\n * 心理评测模块\n * \n * @description\n * 提供心理评测相关功能,包括:\n * - 发起心理评测会话\n * - 提交心理评测答题\n * - 获取评测详情和结果\n * - 获取答题记录\n * \n * @example\n * ```typescript\n * import { PlolinkClient } from '@plolink/sdk';\n * \n * const client = new PlolinkClient({\n * token: 'sk-your-api-key'\n * });\n * \n * // 发起心理评测\n * const initResult = await client.psychologyTest.initiate({\n * groupCodes: ['family_parenting', 'disc'],\n * businessModule: 'talent_assessment',\n * businessCode: 'job_match',\n * businessId: 'clxxxx123456',\n * needAnalysis: true,\n * analysisPrompt: '请结合家庭养育方式和DISC行为模式,分析候选人的性格特点。'\n * });\n * console.log(`评测会话已创建: ${initResult.sessionId}`);\n * console.log(`共 ${initResult.totalCount} 道题目`);\n * \n * // 用户答题...\n * const answers = initResult.questions.map(q => ({\n * groupCode: q.groupCode,\n * bankId: q.bankId,\n * questionId: q.questionId,\n * questionCode: q.questionCode,\n * answer: getUserAnswer(q), // 获取用户答案\n * timeSpent: getTimeSpent(q) // 获取答题时间\n * }));\n * \n * // 提交心理评测\n * const submitResult = await client.psychologyTest.submit({\n * sessionId: initResult.sessionId,\n * answers,\n * duration: 480000\n * });\n * console.log('得分描述:', submitResult.scoreDescription);\n * \n * // 查询评测详情\n * const detail = await client.psychologyTest.getDetail(initResult.sessionId);\n * if (detail.analysisStatus === 'COMPLETED') {\n * console.log('AI分析结果:', detail.analysisResult);\n * }\n * ```\n * \n * @module psychology-test\n */\n\nimport { PlolinkClient } from '../../core/client';\nimport { PlolinkError } from '../../core/error';\nimport type {\n CreatePsychologyTestSessionParams,\n CreatePsychologyTestSessionResponse,\n GetSessionQuestionsResponse,\n InitiatePsychologyTestParams,\n InitiatePsychologyTestResponse,\n SubmitPsychologyTestParams,\n SubmitPsychologyTestResponse,\n PsychologyTestDetail,\n PsychologyTestAnswerDetail,\n ListPsychologyTestSessionsParams,\n ListPsychologyTestSessionsResponse,\n PsychologyBankGroupSummary,\n} from '../../types/psychology-test';\n\nexport type {\n PsychologyTestStatus,\n PsychologyAnalysisStatus,\n QuestionType,\n QuestionDependency,\n QuestionOption,\n QuestionMetadata,\n QuestionInfo,\n GroupSummary,\n CreatePsychologyTestSessionParams,\n CreatePsychologyTestSessionResponse,\n GetSessionQuestionsResponse,\n InitiatePsychologyTestParams,\n InitiatePsychologyTestResponse,\n AnswerRecord,\n SubmitPsychologyTestParams,\n TestCalculationResult,\n SubmitPsychologyTestResponse,\n PsychologyTestAnswerDetail,\n PsychologyTestDetail,\n PsychologyTestWebhookData,\n ListPsychologyTestSessionsParams,\n ListPsychologyTestSessionsResponse,\n PsychologyBankGroupSummary,\n} from '../../types/psychology-test';\n\n/**\n * 心理评测模块\n */\nexport class PsychologyTest {\n private client: PlolinkClient;\n\n constructor(client: PlolinkClient) {\n this.client = client;\n }\n\n /**\n * 创建心理评测会话\n * \n * @description\n * 创建心理评测会话记录(不返回题目)。\n * 创建后需要调用 getSessionQuestions() 获取题目列表。\n * \n * @param params - 创建会话参数\n * @returns 会话信息,包含会话ID\n * @throws {PlolinkError} 当参数验证失败或创建失败时抛出\n * \n * @example\n * ```typescript\n * // 1. 创建会话\n * const { sessionId } = await client.psychologyTest.createTestSession({\n * groupCodes: ['family_parenting', 'disc'],\n * businessModule: 'talent_assessment',\n * businessCode: 'job_match',\n * businessId: 'clxxxx123456',\n * needAnalysis: true,\n * analysisPrompt: '请结合家庭养育方式和DISC行为模式,分析候选人的性格特点。'\n * });\n * \n * console.log(`评测会话已创建: ${sessionId}`);\n * \n * // 2. 获取题目\n * const questions = await client.psychologyTest.getSessionQuestions(sessionId);\n * ```\n */\n public async createTestSession(params: CreatePsychologyTestSessionParams): Promise<CreatePsychologyTestSessionResponse> {\n this.client.logger.info('Creating psychology test session', {\n groupCodes: params.groupCodes,\n businessModule: params.businessModule,\n businessCode: params.businessCode,\n needAnalysis: params.needAnalysis,\n });\n\n // 参数校验\n if (!params.groupCodes || params.groupCodes.length === 0) {\n throw new PlolinkError(\n 'groupCodes is required and cannot be empty',\n 'VALIDATION_ERROR'\n );\n }\n\n if (!params.businessModule || !params.businessCode || !params.businessId) {\n throw new PlolinkError(\n 'businessModule, businessCode, and businessId are required',\n 'VALIDATION_ERROR'\n );\n }\n\n if (params.needAnalysis && !params.analysisPrompt) {\n throw new PlolinkError(\n 'analysisPrompt is required when needAnalysis is true',\n 'VALIDATION_ERROR'\n );\n }\n\n try {\n const response = await this.client.axiosInstance.post<CreatePsychologyTestSessionResponse>(\n '/api/v1/psychology/test-sessions',\n params\n );\n\n this.client.logger.info('Psychology test session created successfully', {\n sessionId: response.sessionId,\n });\n\n return response;\n } catch (error) {\n this.client.logger.error('Failed to create psychology test session', { error });\n throw error;\n }\n }\n\n /**\n * 获取会话题目\n * \n * @description\n * 获取心理评测会话的题目列表(动态生成,每次调用都会重新打乱题目顺序)。\n * \n * @param sessionId - 评测会话ID\n * @returns 题目列表和题组摘要\n * @throws {PlolinkError} 当会话不存在或获取失败时抛出\n * \n * @example\n * ```typescript\n * const questions = await client.psychologyTest.getSessionQuestions('clxxxx789012');\n * \n * console.log(`共 ${questions.totalCount} 道题目`);\n * console.log('题组摘要:', questions.groupSummary);\n * \n * // 展示题目\n * questions.questions.forEach((q, index) => {\n * console.log(`题目 ${index + 1}: ${q.content}`);\n * });\n * ```\n */\n public async getSessionQuestions(sessionId: string): Promise<GetSessionQuestionsResponse> {\n this.client.logger.info('Getting session questions', { sessionId });\n\n if (!sessionId) {\n throw new PlolinkError('sessionId is required', 'VALIDATION_ERROR');\n }\n\n try {\n const response = await this.client.axiosInstance.get<GetSessionQuestionsResponse>(\n `/api/v1/psychology/test-sessions/${sessionId}/questions`\n );\n\n this.client.logger.info('Session questions retrieved successfully', {\n sessionId,\n totalCount: response.totalCount,\n });\n\n return response;\n } catch (error) {\n this.client.logger.error('Failed to get session questions', { error, sessionId });\n throw error;\n }\n }\n\n /**\n * 发起心理评测(已废弃)\n * \n * @deprecated 此方法已废弃,将在 v2.0 中移除。请使用 createTestSession() + getSessionQuestions() 替代。\n * \n * @description\n * 根据题组代码列表发起心理评测会话,系统会自动生成打乱后的题目列表并返回。\n * \n * **迁移建议**:\n * ```typescript\n * // 旧方式(已废弃)\n * const result = await client.psychologyTest.initiate(params);\n * \n * // 新方式(推荐)\n * const { sessionId } = await client.psychologyTest.createTestSession(params);\n * const result = await client.psychologyTest.getSessionQuestions(sessionId);\n * ```\n * \n * @param params - 发起评测参数\n * @returns 评测会话信息,包含会话ID和题目列表\n * @throws {PlolinkError} 当参数验证失败或发起失败时抛出\n */\n public async initiate(params: InitiatePsychologyTestParams): Promise<InitiatePsychologyTestResponse> {\n this.client.logger.warn('Using deprecated initiate() method. Please use createTestSession() + getSessionQuestions() instead.');\n \n this.client.logger.info('Initiating psychology test (deprecated)', {\n groupCodes: params.groupCodes,\n businessModule: params.businessModule,\n businessCode: params.businessCode,\n needAnalysis: params.needAnalysis,\n });\n\n // 参数校验\n if (!params.groupCodes || params.groupCodes.length === 0) {\n throw new PlolinkError(\n 'groupCodes is required and cannot be empty',\n 'VALIDATION_ERROR'\n );\n }\n\n if (!params.businessModule || !params.businessCode || !params.businessId) {\n throw new PlolinkError(\n 'businessModule, businessCode, and businessId are required',\n 'VALIDATION_ERROR'\n );\n }\n\n if (params.needAnalysis && !params.analysisPrompt) {\n throw new PlolinkError(\n 'analysisPrompt is required when needAnalysis is true',\n 'VALIDATION_ERROR'\n );\n }\n\n try {\n // 内部调用新方法实现兼容\n const { sessionId } = await this.createTestSession(params);\n const questionsData = await this.getSessionQuestions(sessionId);\n\n const response: InitiatePsychologyTestResponse = {\n sessionId,\n ...questionsData,\n };\n\n this.client.logger.info('Psychology test initiated successfully (deprecated)', {\n sessionId: response.sessionId,\n totalCount: response.totalCount,\n });\n\n return response;\n } catch (error) {\n this.client.logger.error('Failed to initiate psychology test', { error });\n throw error;\n }\n }\n\n /**\n * 提交心理评测\n * \n * @description\n * 提交心理评测答题数据,系统会自动计算得分并生成 Markdown 描述。\n * 如需 AI 分析则会加入异步队列,分析完成后会通过 Webhook 通知。\n * \n * @param params - 提交评测参数\n * @returns 提交结果,包含计算结果和得分描述\n * @throws {PlolinkError} 当参数验证失败或提交失败时抛出\n * \n * @example\n * ```typescript\n * const result = await client.psychologyTest.submit({\n * sessionId: 'clxxxx789012',\n * answers: [\n * {\n * groupCode: 'family_parenting',\n * bankId: 'bank_123',\n * questionId: 'q_001',\n * questionCode: 'FP001A',\n * answer: '1',\n * timeSpent: 3500\n * },\n * // ... 更多答题记录\n * ],\n * duration: 480000\n * });\n * \n * console.log('得分描述:', result.scoreDescription);\n * console.log('计算结果:', result.calculationResults);\n * ```\n */\n public async submit(params: SubmitPsychologyTestParams): Promise<SubmitPsychologyTestResponse> {\n this.client.logger.info('Submitting psychology test', {\n sessionId: params.sessionId,\n answersCount: params.answers.length,\n });\n\n // 参数校验\n if (!params.sessionId) {\n throw new PlolinkError(\n 'sessionId is required',\n 'VALIDATION_ERROR'\n );\n }\n\n if (!params.answers || params.answers.length === 0) {\n throw new PlolinkError(\n 'answers is required and cannot be empty',\n 'VALIDATION_ERROR'\n );\n }\n\n try {\n const response = await this.client.axiosInstance.post<SubmitPsychologyTestResponse>(\n '/api/v1/psychology/test-sessions/submit',\n params\n );\n\n this.client.logger.info('Psychology test submitted successfully', {\n sessionId: response.sessionId,\n });\n\n return response;\n } catch (error) {\n this.client.logger.error('Failed to submit psychology test', { error });\n throw error;\n }\n }\n\n /**\n * 获取心理评测详情\n * \n * @description\n * 获取心理评测会话的完整信息,包括基本信息、计算结果、得分描述、AI分析结果等。\n * \n * @param sessionId - 评测会话ID\n * @returns 评测会话详情\n * @throws {PlolinkError} 当会话不存在或查询失败时抛出\n * \n * @example\n * ```typescript\n * const detail = await client.psychologyTest.getDetail('clxxxx789012');\n * \n * console.log('评测状态:', detail.status);\n * console.log('得分描述:', detail.scoreDescription);\n * \n * // 检查分析状态\n * if (detail.analysisStatus === 'COMPLETED') {\n * console.log('AI分析结果:', detail.analysisResult);\n * } else if (detail.analysisStatus === 'ANALYZING') {\n * console.log('AI分析进行中,请稍后查询');\n * } else if (detail.analysisStatus === 'FAILED') {\n * console.error('分析失败:', detail.analysisError);\n * }\n * ```\n */\n public async getDetail(sessionId: string): Promise<PsychologyTestDetail> {\n this.client.logger.info('Getting psychology test detail', { sessionId });\n\n if (!sessionId) {\n throw new PlolinkError(\n 'sessionId is required',\n 'VALIDATION_ERROR'\n );\n }\n\n try {\n const response = await this.client.axiosInstance.get<PsychologyTestDetail>(\n `/api/v1/psychology/test-sessions/${sessionId}`\n );\n\n this.client.logger.info('Psychology test detail retrieved successfully', {\n sessionId,\n status: response.status,\n analysisStatus: response.analysisStatus,\n });\n\n return response;\n } catch (error) {\n this.client.logger.error('Failed to get psychology test detail', { error });\n throw error;\n }\n }\n\n /**\n * 获取心理评测答题记录\n * \n * @description\n * 获取心理评测会话的所有答题记录。\n * \n * @param sessionId - 评测会话ID\n * @returns 答题记录列表\n * @throws {PlolinkError} 当会话不存在或查询失败时抛出\n * \n * @example\n * ```typescript\n * const answers = await client.psychologyTest.getAnswers('clxxxx789012');\n * \n * console.log(`共 ${answers.length} 条答题记录`);\n * answers.forEach(answer => {\n * console.log(`题目 ${answer.questionCode}: ${answer.answer}`);\n * });\n * ```\n */\n public async getAnswers(sessionId: string): Promise<PsychologyTestAnswerDetail[]> {\n this.client.logger.info('Getting psychology test answers', { sessionId });\n\n if (!sessionId) {\n throw new PlolinkError(\n 'sessionId is required',\n 'VALIDATION_ERROR'\n );\n }\n\n try {\n const response = await this.client.axiosInstance.get<PsychologyTestAnswerDetail[]>(\n `/api/v1/psychology/test-sessions/${sessionId}/answers`\n );\n\n this.client.logger.info('Psychology test answers retrieved successfully', {\n sessionId,\n count: response.length,\n });\n\n return response;\n } catch (error) {\n this.client.logger.error('Failed to get psychology test answers', { error });\n throw error;\n }\n }\n\n /**\n * 列表查询心理评测会话\n * \n * @description\n * 查询心理评测会话列表,支持分页和多条件筛选。\n * 此接口通常用于管理后台或业务系统查询评测记录。\n * \n * @param params - 查询参数\n * @returns 会话列表和分页信息\n * @throws {PlolinkError} 当查询失败时抛出\n * \n * @example\n * ```typescript\n * // 查询所有评测会话\n * const result = await client.psychologyTest.listTestSessions({\n * page: 1,\n * size: 20\n * });\n * \n * console.log(`共 ${result.total} 条记录`);\n * result.list.forEach(session => {\n * console.log(`会话ID: ${session.id}, 状态: ${session.status}`);\n * });\n * \n * // 按条件筛选\n * const filtered = await client.psychologyTest.listTestSessions({\n * page: 1,\n * size: 20,\n * businessModule: 'talent_assessment',\n * status: 'COMPLETED',\n * analysisStatus: 'COMPLETED'\n * });\n * ```\n */\n public async listTestSessions(\n params: ListPsychologyTestSessionsParams = {}\n ): Promise<ListPsychologyTestSessionsResponse> {\n this.client.logger.info('Listing psychology test sessions', { params });\n\n try {\n // 构建查询参数\n const queryParams = new URLSearchParams();\n if (params.page !== undefined) queryParams.append('page', String(params.page));\n if (params.size !== undefined) queryParams.append('size', String(params.size));\n if (params.businessModule) queryParams.append('businessModule', params.businessModule);\n if (params.businessCode) queryParams.append('businessCode', params.businessCode);\n if (params.status) queryParams.append('status', params.status);\n if (params.analysisStatus) queryParams.append('analysisStatus', params.analysisStatus);\n if (params.startDate) queryParams.append('startDate', params.startDate);\n if (params.endDate) queryParams.append('endDate', params.endDate);\n if (params.teamId) queryParams.append('teamId', params.teamId);\n\n const url = `/api/admin/psychology/test-sessions${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;\n const response = await this.client.axiosInstance.get<ListPsychologyTestSessionsResponse>(url);\n\n this.client.logger.info('Psychology test sessions listed successfully', {\n total: response.total,\n count: response.list.length,\n });\n\n return response;\n } catch (error) {\n this.client.logger.error('Failed to list psychology test sessions', { error });\n throw error;\n }\n }\n\n /**\n * 删除心理评测会话\n * \n * @description\n * 软删除心理评测会话记录。删除后数据不会真正从数据库移除,\n * 但在正常查询中不会显示。此接口通常用于管理后台。\n * \n * @param sessionId - 评测会话ID\n * @returns void\n * @throws {PlolinkError} 当会话不存在或删除失败时抛出\n * \n * @example\n * ```typescript\n * // 删除评测会话\n * await client.psychologyTest.deleteTestSession('clxxxx789012');\n * console.log('评测会话已删除');\n * ```\n */\n public async deleteTestSession(sessionId: string): Promise<void> {\n this.client.logger.info('Deleting psychology test session', { sessionId });\n\n if (!sessionId) {\n throw new PlolinkError(\n 'sessionId is required',\n 'VALIDATION_ERROR'\n );\n }\n\n try {\n await this.client.axiosInstance.delete(\n `/api/admin/psychology/test-sessions/${sessionId}`\n );\n\n this.client.logger.info('Psychology test session deleted successfully', {\n sessionId,\n });\n } catch (error) {\n this.client.logger.error('Failed to delete psychology test session', { error });\n throw error;\n }\n }\n\n /**\n * 获取题库组列表\n * \n * @description\n * 获取所有启用状态的题库组列表,返回基本信息用于选择。\n * 此接口不需要管理员权限,普通用户即可调用。\n * \n * @returns 题库组列表\n * @throws {PlolinkError} 当查询失败时抛出\n * \n * @example\n * ```typescript\n * const groups = await client.psychologyTest.listBankGroups();\n * groups.forEach(g => {\n * console.log(`${g.name} (${g.code}): ${g.testObjective}`);\n * });\n * ```\n */\n public async listBankGroups(): Promise<PsychologyBankGroupSummary[]> {\n this.client.logger.info('Listing psychology bank groups');\n\n try {\n const response = await this.client.axiosInstance.get<PsychologyBankGroupSummary[]>(\n '/api/v1/psychology/bank-groups'\n );\n\n this.client.logger.info('Psychology bank groups listed successfully', {\n count: response.length,\n });\n\n return response;\n } catch (error) {\n this.client.logger.error('Failed to list psychology bank groups', { error });\n throw error;\n }\n }\n}\n","import type { SDKConfig } from '../types';\nimport { InternalLogger } from './logger';\nimport { createAxiosInstance, type TypedAxiosInstance } from './request';\nimport { PlolinkError } from './error';\nimport { PsychologyTest } from '../modules/psychology-test';\n\n/**\n * Plolink SDK 客户端主类\n * \n * @description\n * PlolinkClient 是 SDK 的核心类,负责:\n * - 管理 SDK 配置(认证 Token、API 地址等)\n * - 初始化 Axios 实例并配置拦截器\n * - 提供统一的日志接口\n * - 作为所有业务模块的基础依赖\n * \n * @example\n * ```typescript\n * // 使用 ApiKey\n * const client = new PlolinkClient({\n * token: 'sk-123456789',\n * logger: (level, msg, data) => {\n * console.log(`[${level}] ${msg}`, data);\n * }\n * });\n * \n * // 使用 SessionId (登录后获取)\n * const client = new PlolinkClient({\n * token: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',\n * baseUrl: 'https://api.plolink.com'\n * });\n * ```\n */\nexport class PlolinkClient {\n /**\n * SDK 配置对象(已填充默认值)\n */\n public readonly config: Required<SDKConfig>;\n\n /**\n * Axios 实例,用于发起 HTTP 请求\n */\n public readonly axiosInstance: TypedAxiosInstance;\n\n /**\n * 内部日志记录器\n */\n public readonly logger: InternalLogger;\n\n /**\n * 心理评测模块\n */\n public readonly psychologyTest: PsychologyTest;\n\n /**\n * 创建一个 PlolinkClient 实例\n * \n * @param config - SDK 配置对象\n * @throws {PlolinkError} 当配置验证失败时抛出\n * \n * @example\n * ```typescript\n * const client = new PlolinkClient({\n * token: 'sk-your-api-key'\n * });\n * ```\n */\n constructor(config: SDKConfig) {\n // 验证配置\n this.validateConfig(config);\n\n // 填充默认配置\n this.config = {\n baseUrl: config.baseUrl || 'https://hiring.djangotech.com/',\n token: config.token,\n timeout: config.timeout || 10000,\n logger: config.logger || (() => {}),\n };\n\n // 初始化日志记录器\n this.logger = new InternalLogger(this.config.logger);\n\n this.logger.info('Initializing Plolink SDK Client', {\n baseUrl: this.config.baseUrl,\n timeout: this.config.timeout,\n hasToken: !!this.config.token,\n });\n\n // 创建 Axios 实例\n this.axiosInstance = createAxiosInstance(\n this.config,\n this.logger\n ) as TypedAxiosInstance;\n\n // 初始化业务模块\n this.psychologyTest = new PsychologyTest(this);\n }\n\n /**\n * 验证 SDK 配置\n * \n * @param config - SDK 配置对象\n * @throws {PlolinkError} 当配置不合法时抛出\n * @private\n */\n private validateConfig(config: SDKConfig): void {\n // 验证必填字段 token\n if (!config.token) {\n throw new PlolinkError(\n 'Config validation failed: token is required',\n 'CONFIG_ERROR'\n );\n }\n\n // 验证 token 格式(ApiKey 或 SessionId)\n const isApiKey = config.token.startsWith('sk-');\n const isSessionId = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(config.token);\n \n if (!isApiKey && !isSessionId) {\n throw new PlolinkError(\n 'Config validation failed: token must be either an ApiKey (sk-xxx) or a SessionId (UUID format)',\n 'CONFIG_ERROR'\n );\n }\n\n // 验证 baseUrl 格式\n if (config.baseUrl) {\n try {\n new URL(config.baseUrl);\n } catch {\n throw new PlolinkError(\n `Config validation failed: baseUrl is not a valid URL: ${config.baseUrl}`,\n 'CONFIG_ERROR'\n );\n }\n }\n\n // 验证 timeout\n if (config.timeout !== undefined && (config.timeout <= 0 || !Number.isFinite(config.timeout))) {\n throw new PlolinkError(\n `Config validation failed: timeout must be a positive number, got ${config.timeout}`,\n 'CONFIG_ERROR'\n );\n }\n }\n\n /**\n * 获取当前 SDK 版本\n * \n * @returns SDK 版本号\n */\n public getVersion(): string {\n return '1.0.0';\n }\n\n /**\n * 检查客户端健康状态\n * \n * @returns 健康状态信息\n * \n * @example\n * ```typescript\n * const health = client.healthCheck();\n * console.log(health);\n * // { status: 'ok', baseUrl: '...', version: '...' }\n * ```\n */\n public healthCheck(): {\n status: 'ok';\n baseUrl: string;\n version: string;\n hasToken: boolean;\n } {\n return {\n status: 'ok',\n baseUrl: this.config.baseUrl,\n version: this.getVersion(),\n hasToken: !!this.config.token,\n };\n }\n}\n\n","/**\n * 信息同步模块\n * \n * @description\n * 提供信息同步功能,包括:\n * - Webhook 配置管理(创建/查询/更新/删除)\n * - 同步记录查询\n * - 手动重试\n * - 签名验证工具(用于验证 Webhook 请求)\n * \n * @example\n * ```typescript\n * import { PlolinkClient } from '@plolink/sdk';\n * \n * const client = new PlolinkClient({\n * token: 'your-session-id-or-api-key'\n * });\n * \n * // 创建 Webhook 配置\n * const result = await client.infoSync.createWebhookConfig({\n * name: 'Production Webhook',\n * url: 'https://example.com/webhook/plolink',\n * modules: ['report-writer', 'video-psych-analysis']\n * });\n * console.log(`SecretKey (仅展示一次): ${result.secretKey}`);\n * \n * // 查询同步记录\n * const records = await client.infoSync.listSyncRecords({\n * businessModule: 'report-writer',\n * status: 'FAILED'\n * });\n * console.log(`找到 ${records.total} 条失败记录`);\n * ```\n * \n * @module info-sync\n */\n\nimport { PlolinkClient } from '../../core/client';\nimport { PlolinkError } from '../../core/error';\nimport type {\n WebhookConfig,\n CreateWebhookConfigParams,\n CreateWebhookConfigResponse,\n UpdateWebhookConfigParams,\n InfoSyncRecord,\n InfoSyncQueryParams,\n InfoSyncListResponse,\n} from '../../types/info-sync';\n\nexport type {\n WebhookConfig,\n CreateWebhookConfigParams,\n CreateWebhookConfigResponse,\n UpdateWebhookConfigParams,\n InfoSyncRecord,\n InfoSyncHistoryItem,\n InfoSyncQueryParams,\n InfoSyncListResponse,\n InfoSyncPayload,\n InfoSyncType,\n InfoSyncStatus,\n} from '../../types/info-sync';\n\nexport { InfoSyncSignature } from '../../common/signature';\n\n/**\n * 信息同步模块\n */\nexport class InfoSync {\n private client: PlolinkClient;\n\n constructor(client: PlolinkClient) {\n this.client = client;\n }\n\n // ==================== Webhook 配置管理 ====================\n\n /**\n * 创建 Webhook 配置\n * \n * @description\n * 为当前团队创建一个新的 Webhook 配置。\n * 返回的 secretKey 仅在创建时返回一次,请立即保存。\n * \n * 每个团队最多可以创建 10 个 Webhook 配置。\n * \n * ⚠️ 重要: secretKey 仅在创建时返回,后续无法再次获取,请妥善保存\n * \n * @param params - 创建参数\n * @returns 创建结果,包含配置 ID 和密钥\n * @throws {PlolinkError} 当参数无效、配置数量超限或权限不足时抛出\n * \n * @example\n * ```typescript\n * const result = await infoSync.createWebhookConfig({\n * name: 'Production Webhook',\n * url: 'https://example.com/webhook/plolink',\n * modules: ['report-writer', 'video-psych-analysis']\n * });\n * \n * console.log(`配置 ID: ${result.id}`);\n * console.log(`SecretKey: ${result.secretKey}`);\n * // 请立即保存 secretKey,后续无法再次获取\n * ```\n */\n public async createWebhookConfig(\n params: CreateWebhookConfigParams\n ): Promise<CreateWebhookConfigResponse> {\n // 参数验证\n if (!params.name || params.name.trim().length === 0) {\n throw new PlolinkError('name is required and cannot be empty', 'INVALID_PARAMS');\n }\n\n if (!params.url || params.url.trim().length === 0) {\n throw new PlolinkError('url is required and cannot be empty', 'INVALID_PARAMS');\n }\n\n if (!params.url.startsWith('http://') && !params.url.startsWith('https://')) {\n throw new PlolinkError('url must start with http:// or https://', 'INVALID_PARAMS');\n }\n\n if (!Array.isArray(params.modules)) {\n throw new PlolinkError('modules must be an array', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.post('/api/v1/info-sync/webhook-configs', params);\n }\n\n /**\n * 获取 Webhook 配置列表\n * \n * @description\n * 获取当前团队的所有 Webhook 配置。\n * 注意:列表中不包含 secretKey。\n * \n * @returns Webhook 配置列表\n * @throws {PlolinkError} 当权限不足时抛出\n * \n * @example\n * ```typescript\n * const configs = await infoSync.listWebhookConfigs();\n * configs.forEach(config => {\n * console.log(`${config.name}: ${config.url}`);\n * console.log(`订阅模块: ${config.modules.join(', ')}`);\n * console.log(`状态: ${config.enabled ? '启用' : '禁用'}`);\n * });\n * ```\n */\n public async listWebhookConfigs(): Promise<WebhookConfig[]> {\n return this.client.axiosInstance.get('/api/v1/info-sync/webhook-configs');\n }\n\n /**\n * 获取 Webhook 配置详情\n * \n * @description\n * 获取指定 Webhook 配置的详细信息。\n * 注意:不包含 secretKey。\n * \n * @param id - 配置 ID\n * @returns Webhook 配置详情\n * @throws {PlolinkError} 当配置不存在或权限不足时抛出\n * \n * @example\n * ```typescript\n * const config = await infoSync.getWebhookConfig('config-123');\n * console.log(`名称: ${config.name}`);\n * console.log(`URL: ${config.url}`);\n * console.log(`订阅模块: ${config.modules.join(', ')}`);\n * ```\n */\n public async getWebhookConfig(id: string): Promise<WebhookConfig> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/info-sync/webhook-configs/${id}`);\n }\n\n /**\n * 更新 Webhook 配置\n * \n * @description\n * 更新指定 Webhook 配置的信息。\n * 注意:不能更新 secretKey,如需更换密钥请删除后重新创建。\n * \n * @param id - 配置 ID\n * @param params - 更新参数\n * @throws {PlolinkError} 当参数无效、配置不存在或权限不足时抛出\n * \n * @example\n * ```typescript\n * // 禁用配置\n * await infoSync.updateWebhookConfig('config-123', {\n * enabled: false\n * });\n * \n * // 更新订阅模块\n * await infoSync.updateWebhookConfig('config-123', {\n * modules: ['report-writer']\n * });\n * \n * // 更新 URL\n * await infoSync.updateWebhookConfig('config-123', {\n * url: 'https://new-url.example.com/webhook'\n * });\n * ```\n */\n public async updateWebhookConfig(\n id: string,\n params: UpdateWebhookConfigParams\n ): Promise<void> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n if (params.url && (!params.url.startsWith('http://') && !params.url.startsWith('https://'))) {\n throw new PlolinkError('url must start with http:// or https://', 'INVALID_PARAMS');\n }\n\n if (params.modules !== undefined && !Array.isArray(params.modules)) {\n throw new PlolinkError('modules must be an array', 'INVALID_PARAMS');\n }\n\n await this.client.axiosInstance.put(`/api/v1/info-sync/webhook-configs/${id}`, params);\n }\n\n /**\n * 删除 Webhook 配置\n * \n * @description\n * 永久删除指定的 Webhook 配置(软删除)。\n * 删除后该配置将不再接收 Webhook 通知。\n * \n * ⚠️ 警告: 此操作不可逆,请确认后再执行\n * \n * @param id - 配置 ID\n * @throws {PlolinkError} 当配置不存在或权限不足时抛出\n * \n * @example\n * ```typescript\n * await infoSync.deleteWebhookConfig('config-123');\n * console.log('Webhook 配置已删除');\n * ```\n */\n public async deleteWebhookConfig(id: string): Promise<void> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n await this.client.axiosInstance.delete(`/api/v1/info-sync/webhook-configs/${id}`);\n }\n\n // ==================== 同步记录查询 ====================\n\n /**\n * 查询同步记录列表\n * \n * @description\n * 查询当前团队的同步记录,支持多种过滤条件和分页。\n * \n * @param params - 查询参数\n * @returns 分页的同步记录列表\n * @throws {PlolinkError} 当参数无效或权限不足时抛出\n * \n * @example\n * ```typescript\n * // 查询所有记录\n * const result = await infoSync.listSyncRecords();\n * console.log(`共 ${result.total} 条记录`);\n * \n * // 查询失败的 Webhook 同步记录\n * const failed = await infoSync.listSyncRecords({\n * type: 'WEBHOOK',\n * status: 'FAILED'\n * });\n * console.log(`${failed.total} 条 Webhook 同步失败`);\n * \n * // 查询报告写作模块的记录\n * const reports = await infoSync.listSyncRecords({\n * businessModule: 'report-writer',\n * page: 1,\n * pageSize: 20\n * });\n * ```\n */\n public async listSyncRecords(\n params?: InfoSyncQueryParams\n ): Promise<InfoSyncListResponse> {\n return this.client.axiosInstance.get('/api/v1/info-sync/sync-records', {\n params: params || {}\n });\n }\n\n /**\n * 获取同步记录详情\n * \n * @description\n * 获取指定同步记录的详细信息,包括完整的历史记录。\n * \n * @param id - 记录 ID\n * @returns 同步记录详情\n * @throws {PlolinkError} 当记录不存在或权限不足时抛出\n * \n * @example\n * ```typescript\n * const record = await infoSync.getSyncRecord('record-123');\n * console.log(`业务模块: ${record.businessModule}`);\n * console.log(`业务代码: ${record.businessCode}`);\n * console.log(`状态: ${record.status}`);\n * console.log(`历史记录:`);\n * record.history.forEach(item => {\n * console.log(` ${new Date(item.time).toLocaleString()}: ${item.status} - ${item.message || ''}`);\n * });\n * ```\n */\n public async getSyncRecord(id: string): Promise<InfoSyncRecord> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/info-sync/sync-records/${id}`);\n }\n\n /**\n * 手动重试同步任务\n * \n * @description\n * 手动重试失败的同步任务。\n * 只能重试状态为 FAILED 的记录。\n * \n * 重试后记录状态将变为 PENDING,并重新提交到队列处理。\n * \n * @param id - 记录 ID\n * @throws {PlolinkError} 当记录不存在、状态不是 FAILED 或权限不足时抛出\n * \n * @example\n * ```typescript\n * // 查询失败记录\n * const failed = await infoSync.listSyncRecords({ status: 'FAILED' });\n * \n * // 重试所有失败记录\n * for (const record of failed.list) {\n * try {\n * await infoSync.retrySyncRecord(record.id);\n * console.log(`已重试: ${record.id}`);\n * } catch (error) {\n * console.error(`重试失败: ${record.id}`, error);\n * }\n * }\n * ```\n */\n public async retrySyncRecord(id: string): Promise<void> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n await this.client.axiosInstance.post(`/api/v1/info-sync/sync-records/${id}/retry`);\n }\n}\n","/**\n * Plolink SDK 主入口\n * \n * @description\n * Plolink 开放平台官方 SDK,提供完整的 API 调用能力。\n * \n * @packageDocumentation\n * \n * @example\n * ```typescript\n * import { PlolinkClient } from '@plolink/sdk';\n * \n * // 创建客户端实例\n * const client = new PlolinkClient({\n * token: 'sk-your-api-key',\n * logger: (level, message, data) => {\n * console.log(`[${level}] ${message}`, data);\n * }\n * });\n * \n * // 检查健康状态\n * const health = client.healthCheck();\n * console.log(health);\n * ```\n */\n\n// 导出核心类\nexport { PlolinkClient } from './core/client';\nexport { PlolinkError } from './core/error';\nexport { InternalLogger } from './core/logger';\n\n// 导出公共工具(供高级用户使用)\nexport { Poller } from './common/poller';\nexport { EventEmitter, TypedEventEmitter } from './common/hooks';\nexport {\n isNode,\n isBrowser,\n isWebWorker,\n getEnvironment,\n environmentInfo,\n} from './common/adapter';\nexport { InfoSyncSignature } from './common/signature';\n\n// 导出业务模块\nexport { InfoSync } from './modules/info-sync';\nexport { PsychologyTest } from './modules/psychology-test';\n\n// 导出类型定义\nexport type {\n SDKConfig,\n LogLevel,\n LoggerFunction,\n PollerOptions,\n PollerSnapshot,\n // shared (跨模块通用类型)\n RoleType,\n ScopeType,\n AssignRoleParams,\n} from './types';\n\n// 导出版本信息\nexport const VERSION = '1.0.0';\n\n/**\n * SDK 默认配置\n */\nexport const DEFAULT_CONFIG = {\n baseUrl: 'https://hiring.djangotech.com/',\n timeout: 10000,\n initialInterval: 1000,\n maxInterval: 30000,\n backoffFactor: 1.5,\n} as const;\n\n"]}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkJR4HYYQI_cjs = require('../../chunk-JR4HYYQI.cjs');
4
3
  var chunkY3UJVC2L_cjs = require('../../chunk-Y3UJVC2L.cjs');
4
+ var chunkJR4HYYQI_cjs = require('../../chunk-JR4HYYQI.cjs');
5
5
 
6
6
  // src/modules/billing/index.ts
7
7
  var Billing = class {
@@ -1,4 +1,4 @@
1
- import { P as PlolinkClient } from '../../client-CAjIQKPm.cjs';
1
+ import { P as PlolinkClient } from '../../client-l6cekf09.cjs';
2
2
  import { P as Poller } from '../../poller-BlIRbwL4.cjs';
3
3
  import '../../core-77EbLgbp.cjs';
4
4
  import 'axios';
@@ -1,4 +1,4 @@
1
- import { P as PlolinkClient } from '../../client-CwNikk7i.js';
1
+ import { P as PlolinkClient } from '../../client-DXKAtLg1.js';
2
2
  import { P as Poller } from '../../poller-DWKZjuSw.js';
3
3
  import '../../core-77EbLgbp.js';
4
4
  import 'axios';
@@ -1,5 +1,5 @@
1
- import { Poller } from '../../chunk-IHAAKFEJ.js';
2
1
  import { PlolinkError } from '../../chunk-MD4O7FWT.js';
2
+ import { Poller } from '../../chunk-IHAAKFEJ.js';
3
3
 
4
4
  // src/modules/billing/index.ts
5
5
  var Billing = class {
@@ -1,4 +1,4 @@
1
- import { P as PlolinkClient } from '../../client-CAjIQKPm.cjs';
1
+ import { P as PlolinkClient } from '../../client-l6cekf09.cjs';
2
2
  import { S as ScopeType, R as RoleType, A as AssignRoleParams } from '../../shared-6ZepUSPW.cjs';
3
3
  import '../../core-77EbLgbp.cjs';
4
4
  import 'axios';
@@ -1,4 +1,4 @@
1
- import { P as PlolinkClient } from '../../client-CwNikk7i.js';
1
+ import { P as PlolinkClient } from '../../client-DXKAtLg1.js';
2
2
  import { S as ScopeType, R as RoleType, A as AssignRoleParams } from '../../shared-6ZepUSPW.js';
3
3
  import '../../core-77EbLgbp.js';
4
4
  import 'axios';
@@ -1,4 +1,4 @@
1
- import { P as PlolinkClient } from '../../client-CAjIQKPm.cjs';
1
+ import { P as PlolinkClient } from '../../client-l6cekf09.cjs';
2
2
  import { R as RoleType, S as ScopeType } from '../../shared-6ZepUSPW.cjs';
3
3
  import '../../core-77EbLgbp.cjs';
4
4
  import 'axios';
@@ -1,4 +1,4 @@
1
- import { P as PlolinkClient } from '../../client-CwNikk7i.js';
1
+ import { P as PlolinkClient } from '../../client-DXKAtLg1.js';
2
2
  import { R as RoleType, S as ScopeType } from '../../shared-6ZepUSPW.js';
3
3
  import '../../core-77EbLgbp.js';
4
4
  import 'axios';
@@ -1,13 +1,28 @@
1
1
  'use strict';
2
2
 
3
- var chunkJR4HYYQI_cjs = require('../../chunk-JR4HYYQI.cjs');
4
3
  var chunkY3UJVC2L_cjs = require('../../chunk-Y3UJVC2L.cjs');
4
+ var chunkJR4HYYQI_cjs = require('../../chunk-JR4HYYQI.cjs');
5
5
 
6
6
  // src/modules/video-psych-analysis/index.ts
7
7
  var VideoPsychAnalysis = class {
8
8
  constructor(client) {
9
9
  this.client = client;
10
10
  }
11
+ /**
12
+ * 获取视频心理分析配置
13
+ *
14
+ * @returns 配置信息(包括语言选项等)
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const config = await videoPsych.getConfig();
19
+ * console.log('语言选项:', config.languageOptions);
20
+ * console.log('默认语言:', config.defaultLanguage);
21
+ * ```
22
+ */
23
+ async getConfig() {
24
+ return this.client.axiosInstance.get("/api/v1/video-psych-analysis/config");
25
+ }
11
26
  /**
12
27
  * 查询分析任务列表
13
28
  *
@@ -53,7 +68,7 @@ var VideoPsychAnalysis = class {
53
68
  * ```
54
69
  */
55
70
  async create(params) {
56
- const { videoFileIds, referenceImageFileId, prompt, frameFps, language, name } = params;
71
+ const { videoFileIds, referenceImageFileId, prompt, familyBackground, frameFps, language, name } = params;
57
72
  if (!videoFileIds || videoFileIds.length === 0) {
58
73
  throw new chunkY3UJVC2L_cjs.PlolinkError("videoFileIds is required and must not be empty", "INVALID_PARAMS");
59
74
  }
@@ -71,6 +86,7 @@ var VideoPsychAnalysis = class {
71
86
  videoFileIds,
72
87
  referenceImageFileId,
73
88
  prompt,
89
+ familyBackground,
74
90
  frameFps,
75
91
  language
76
92
  });
@@ -100,6 +116,67 @@ var VideoPsychAnalysis = class {
100
116
  }
101
117
  return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}`);
102
118
  }
119
+ /**
120
+ * 获取视频元数据信息
121
+ *
122
+ * @description
123
+ * 获取任务的视频元数据信息(videoInfo)。在异步模式下,任务创建时 videoInfo 为空,
124
+ * 需要等待任务进入 PROCESSING 状态后由定时任务自动同步。
125
+ *
126
+ * **使用场景**:
127
+ * - 获取视频的宽高、时长、编码等信息用于界面展示
128
+ * - 在任务创建后轮询此接口直到获取到 videoInfo
129
+ *
130
+ * **注意**:
131
+ * - 如果视频信息尚未生成,返回 null
132
+ * - 建议配合任务状态查询使用,等待状态变为 PROCESSING 后再查询
133
+ *
134
+ * @param id - 任务ID
135
+ * @returns 视频元数据信息,如果尚未生成则返回 null
136
+ * @throws {PlolinkError} 当任务不存在时抛出
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * // 轮询获取 videoInfo
141
+ * const checkVideoInfo = async (analysisId: string) => {
142
+ * const maxAttempts = 60;
143
+ * let attempt = 0;
144
+ *
145
+ * while (attempt < maxAttempts) {
146
+ * const videoInfo = await videoPsych.getVideoInfo(analysisId);
147
+ *
148
+ * if (videoInfo) {
149
+ * console.log(`视频信息: ${videoInfo.width}x${videoInfo.height}`);
150
+ * console.log(`时长: ${videoInfo.duration}s`);
151
+ * console.log(`文件大小: ${(videoInfo.file_size / 1024 / 1024).toFixed(2)}MB`);
152
+ * return videoInfo;
153
+ * }
154
+ *
155
+ * console.log('视频信息还在处理中...');
156
+ * await new Promise(resolve => setTimeout(resolve, 5000)); // 等待5秒
157
+ * attempt++;
158
+ * }
159
+ *
160
+ * throw new Error('获取视频信息超时');
161
+ * };
162
+ *
163
+ * const info = await checkVideoInfo('analysis_123');
164
+ * ```
165
+ */
166
+ async getVideoInfo(id) {
167
+ if (!id) {
168
+ throw new chunkY3UJVC2L_cjs.PlolinkError("id is required", "INVALID_PARAMS");
169
+ }
170
+ try {
171
+ const response = await this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/video-info`);
172
+ return response.videoInfo || null;
173
+ } catch (error) {
174
+ if (error instanceof chunkY3UJVC2L_cjs.PlolinkError && error.code === 404) {
175
+ return null;
176
+ }
177
+ throw error;
178
+ }
179
+ }
103
180
  /**
104
181
  * 更新分析任务
105
182
  *
@@ -124,8 +201,8 @@ var VideoPsychAnalysis = class {
124
201
  if (!id) {
125
202
  throw new chunkY3UJVC2L_cjs.PlolinkError("id is required", "INVALID_PARAMS");
126
203
  }
127
- if (!params.name && !params.prompt) {
128
- throw new chunkY3UJVC2L_cjs.PlolinkError("At least one field (name or prompt) must be provided", "INVALID_PARAMS");
204
+ if (!params.name && !params.prompt && !params.familyBackground) {
205
+ throw new chunkY3UJVC2L_cjs.PlolinkError("At least one field (name, prompt, or familyBackground) must be provided", "INVALID_PARAMS");
129
206
  }
130
207
  return this.client.axiosInstance.patch(`/api/v1/video-psych-analysis/${id}`, params);
131
208
  }
@@ -150,6 +227,48 @@ var VideoPsychAnalysis = class {
150
227
  }
151
228
  return this.client.axiosInstance.delete(`/api/v1/video-psych-analysis/${id}`);
152
229
  }
230
+ /**
231
+ * 重试失败的分析任务
232
+ *
233
+ * @description
234
+ * 对失败(FAILED)状态的任务进行重试,使用原有参数重新提交到AI引擎进行分析。
235
+ * 重试会清空之前的错误信息和分析结果,重新开始完整的分析流程。
236
+ *
237
+ * **注意**:
238
+ * - 只能重试状态为 FAILED 的任务
239
+ * - 重试后任务状态会重置为 PENDING
240
+ * - 会清空之前的分析结果和报告内容
241
+ * - 建议配合 `watchAnalysisStatus()` 方法监听重试后的任务状态
242
+ *
243
+ * @param id - 任务ID
244
+ * @returns 更新后的任务信息
245
+ * @throws {PlolinkError} 当任务不存在、状态不是FAILED或重试失败时抛出
246
+ *
247
+ * @example
248
+ * ```typescript
249
+ * // 重试失败的任务
250
+ * const result = await videoPsych.retry('analysis_123');
251
+ * console.log(`任务已重新提交: ${result.id}`);
252
+ * console.log(`当前状态: ${result.status}`);
253
+ *
254
+ * // 监听重试后的任务状态
255
+ * const poller = videoPsych.watchAnalysisStatus(result.id, (detail) => {
256
+ * console.log(`重试进度: ${detail.progress.done}/${detail.progress.total}`);
257
+ * if (detail.status === 'COMPLETED') {
258
+ * console.log('重试成功,分析完成!');
259
+ * } else if (detail.status === 'FAILED') {
260
+ * console.error('重试后仍失败');
261
+ * }
262
+ * });
263
+ * poller.start();
264
+ * ```
265
+ */
266
+ async retry(id) {
267
+ if (!id) {
268
+ throw new chunkY3UJVC2L_cjs.PlolinkError("id is required", "INVALID_PARAMS");
269
+ }
270
+ return this.client.axiosInstance.post(`/api/v1/video-psych-analysis/${id}/retry`);
271
+ }
153
272
  /**
154
273
  * 同步任务状态
155
274
  *
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/modules/video-psych-analysis/index.ts"],"names":["PlolinkError","Poller"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * 视频人物心理分析模块\n * \n * @description\n * 提供视频人物心理分析相关功能,包括:\n * - 创建分析任务\n * - 查询任务详情和状态\n * - 同步任务状态(轮询)\n * - 获取分析结果(文本/帧/段落维度)\n * - 生成心理分析报告\n * \n * @example\n * ```typescript\n * import { PlolinkClient } from '@plolink/sdk';\n * import { VideoPsychAnalysis } from '@plolink/sdk/video-psych-analysis';\n * \n * const client = new PlolinkClient({\n * mode: 'apiKey',\n * apiKey: 'your-api-key'\n * });\n * \n * const videoPsych = new VideoPsychAnalysis(client);\n * \n * // 创建分析任务\n * const result = await videoPsych.create({\n * name: '候选人A面试分析',\n * videoFileIds: ['file1', 'file2'],\n * referenceImageFileId: 'refImage1',\n * prompt: '请以专业心理分析师的视角进行分析',\n * frameFps: 3,\n * language: 'zh'\n * });\n * console.log(`任务已创建: ${result.id}`);\n * \n * // 轮询任务状态\n * const poller = videoPsych.watchAnalysisStatus(result.id, (detail) => {\n * console.log(`分析进度: ${detail.progress.done}/${detail.progress.total}`);\n * if (detail.status === 'COMPLETED') {\n * console.log('分析完成,报告已生成!');\n * console.log(detail.reportContent);\n * }\n * });\n * ```\n * \n * @module video-psych-analysis\n */\n\nimport { PlolinkClient } from '../../core/client';\nimport { Poller } from '../../common/poller';\nimport { PlolinkError } from '../../core/error';\nimport type {\n CreateVideoPsychAnalysisParams,\n CreateVideoPsychAnalysisResponse,\n VideoPsychAnalysisDetail,\n SyncStatusResponse,\n TextsData,\n FramesData,\n ParagraphsData,\n ListVideoPsychAnalysesParams,\n ListVideoPsychAnalysesResponse,\n UpdateVideoPsychAnalysisParams,\n UpdateVideoPsychAnalysisResponse,\n} from '../../types/video-psych-analysis';\n\nexport type {\n VideoPsychAnalysisStatus,\n CreateVideoPsychAnalysisParams,\n VideoInfo,\n AnalysisProgress,\n CreateVideoPsychAnalysisResponse,\n VideoPsychAnalysisDetail,\n SyncStatusResponse,\n TextAnalysisItem,\n TextsData,\n FrameAnalysisItem,\n FramesData,\n ParagraphAnalysisItem,\n ParagraphsData,\n ListVideoPsychAnalysesParams,\n VideoPsychAnalysisSummary,\n ListVideoPsychAnalysesResponse,\n UpdateVideoPsychAnalysisParams,\n UpdateVideoPsychAnalysisResponse,\n} from '../../types/video-psych-analysis';\n\n/**\n * 视频人物心理分析模块\n */\nexport class VideoPsychAnalysis {\n private client: PlolinkClient;\n\n constructor(client: PlolinkClient) {\n this.client = client;\n }\n\n /**\n * 查询分析任务列表\n * \n * @param params - 查询参数(可选)\n * @returns 任务列表\n * @throws {PlolinkError} 当查询失败时抛出\n * \n * @example\n * ```typescript\n * // 查询所有已完成的任务\n * const result = await videoPsych.list({\n * status: 'COMPLETED',\n * page: 1,\n * pageSize: 20\n * });\n * console.log(`共 ${result.total} 个任务`);\n * result.list.forEach(item => {\n * console.log(`${item.name}: ${item.status}`);\n * });\n * ```\n */\n public async list(params?: ListVideoPsychAnalysesParams): Promise<ListVideoPsychAnalysesResponse> {\n return this.client.axiosInstance.get('/api/v1/video-psych-analysis', { params });\n }\n\n /**\n * 创建视频心理分析任务\n * \n * @param params - 创建参数\n * @returns 创建结果,包含任务ID和初始状态\n * @throws {PlolinkError} 当参数验证失败或创建失败时抛出\n * \n * @example\n * ```typescript\n * const result = await videoPsych.create({\n * name: '候选人A面试分析',\n * videoFileIds: ['file1', 'file2', 'file3'],\n * referenceImageFileId: 'refImage1',\n * prompt: '请以专业心理分析师的视角,分析候选人的情绪、态度和心理状态',\n * frameFps: 3,\n * language: 'zh'\n * });\n * console.log(`任务ID: ${result.id}, 状态: ${result.status}`);\n * ```\n */\n public async create(params: CreateVideoPsychAnalysisParams): Promise<CreateVideoPsychAnalysisResponse> {\n const { videoFileIds, referenceImageFileId, prompt, frameFps, language, name } = params;\n\n // 参数验证\n if (!videoFileIds || videoFileIds.length === 0) {\n throw new PlolinkError('videoFileIds is required and must not be empty', 'INVALID_PARAMS');\n }\n\n if (!referenceImageFileId) {\n throw new PlolinkError('referenceImageFileId is required', 'INVALID_PARAMS');\n }\n\n if (!prompt) {\n throw new PlolinkError('prompt is required', 'INVALID_PARAMS');\n }\n\n if (frameFps !== undefined && (frameFps < 1 || frameFps > 30)) {\n throw new PlolinkError('frameFps must be between 1 and 30', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.post('/api/v1/video-psych-analysis', {\n name,\n videoFileIds,\n referenceImageFileId,\n prompt,\n frameFps,\n language,\n });\n }\n\n /**\n * 获取分析任务详情\n * \n * @param id - 任务ID\n * @returns 任务详情信息\n * @throws {PlolinkError} 当任务不存在或无权访问时抛出\n * \n * @example\n * ```typescript\n * const detail = await videoPsych.getDetail('analysis_123');\n * console.log(`任务: ${detail.name}`);\n * console.log(`状态: ${detail.status}`);\n * console.log(`进度: ${detail.progress.done}/${detail.progress.total}`);\n * \n * if (detail.reportContent) {\n * console.log('报告已生成');\n * }\n * ```\n */\n public async getDetail(id: string): Promise<VideoPsychAnalysisDetail> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}`);\n }\n\n /**\n * 更新分析任务\n * \n * @description\n * 更新分析任务的基本信息(仅限 PENDING 和 FAILED 状态的任务)。\n * \n * @param id - 任务ID\n * @param params - 更新参数\n * @returns 更新后的任务信息\n * @throws {PlolinkError} 当任务不存在、状态不允许更新或更新失败时抛出\n * \n * @example\n * ```typescript\n * const updated = await videoPsych.update('analysis_123', {\n * name: '李四的心理分析',\n * prompt: '请以临床心理学专家的视角进行分析'\n * });\n * console.log(`已更新: ${updated.name}`);\n * ```\n */\n public async update(id: string, params: UpdateVideoPsychAnalysisParams): Promise<UpdateVideoPsychAnalysisResponse> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n if (!params.name && !params.prompt) {\n throw new PlolinkError('At least one field (name or prompt) must be provided', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.patch(`/api/v1/video-psych-analysis/${id}`, params);\n }\n\n /**\n * 删除分析任务\n * \n * @description\n * 删除分析任务(软删除)。\n * \n * @param id - 任务ID\n * @throws {PlolinkError} 当任务不存在或删除失败时抛出\n * \n * @example\n * ```typescript\n * await videoPsych.delete('analysis_123');\n * console.log('任务已删除');\n * ```\n */\n public async delete(id: string): Promise<{ message: string }> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.delete(`/api/v1/video-psych-analysis/${id}`);\n }\n\n /**\n * 同步任务状态\n * \n * @description\n * 主动触发后端从 AI TOOLS API 同步最新状态和中间结果。\n * \n * **注意**:通常不需要手动调用此方法,系统会每30秒自动轮询同步所有非完成态的任务。\n * \n * @param id - 任务ID\n * @returns 同步后的状态信息\n * @throws {PlolinkError} 当任务不存在或同步失败时抛出\n * \n * @example\n * ```typescript\n * const status = await videoPsych.syncStatus('analysis_123');\n * console.log(`当前状态: ${status.status}`);\n * console.log(`进度: ${status.progress.done}/${status.progress.total}`);\n * ```\n */\n public async syncStatus(id: string): Promise<SyncStatusResponse> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/status`);\n }\n\n /**\n * 轮询分析任务状态\n * \n * @description\n * 创建一个轮询器持续监听任务状态变化,直到任务达到终态(COMPLETED/FAILED)。\n * 使用指数退避策略,初始间隔5秒,最大间隔30秒。\n * \n * @param id - 任务ID\n * @param onStatusChange - 状态变化回调函数\n * @returns Poller实例,可用于手动停止轮询\n * \n * @example\n * ```typescript\n * const poller = videoPsych.watchAnalysisStatus('analysis_123', (detail) => {\n * console.log(`状态: ${detail.status}`);\n * console.log(`进度: ${detail.progress.done}/${detail.progress.total} (${detail.progress.stage})`);\n * \n * if (detail.status === 'COMPLETED') {\n * console.log('分析完成,报告已生成!');\n * console.log(detail.reportContent);\n * } else if (detail.status === 'FAILED') {\n * console.error(`分析失败: ${detail.errorMessage}`);\n * }\n * });\n * \n * // 开始轮询\n * poller.start();\n * \n * // 需要时可以手动停止\n * // poller.stop();\n * ```\n */\n public watchAnalysisStatus(\n id: string,\n onStatusChange: (detail: VideoPsychAnalysisDetail) => void\n ): Poller<VideoPsychAnalysisDetail> {\n const poller = new Poller<VideoPsychAnalysisDetail>({\n task: async () => {\n // 先同步状态,再获取详情\n await this.syncStatus(id);\n return this.getDetail(id);\n },\n onResult: onStatusChange,\n shouldStop: (detail) => {\n return ['COMPLETED', 'FAILED'].includes(detail.status);\n },\n initialInterval: 5000, // 5秒\n maxInterval: 30000, // 30秒\n backoffFactor: 1.5,\n onError: (error) => {\n this.client.logger.error('Analysis polling error', { error, id });\n },\n });\n\n // 自动启动\n void poller.start();\n\n return poller;\n }\n\n /**\n * 获取文本维度分析结果\n * \n * @param id - 任务ID\n * @returns 文本维度分析数据\n * @throws {PlolinkError} 当任务不存在或分析未完成时抛出\n * \n * @example\n * ```typescript\n * const texts = await videoPsych.getTexts('analysis_123');\n * console.log(`共 ${texts.total} 条文本`);\n * texts.items.forEach(item => {\n * console.log(`${item.start_time}s: ${item.text}`);\n * if (item.nlp_result) {\n * console.log(` 情绪: ${item.nlp_result.speaker_emotion}`);\n * console.log(` 态度: ${item.nlp_result.real_attitude}`);\n * }\n * });\n * ```\n */\n public async getTexts(id: string): Promise<TextsData> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/texts`);\n }\n\n /**\n * 获取帧维度分析结果\n * \n * @param id - 任务ID\n * @returns 帧维度分析数据\n * @throws {PlolinkError} 当任务不存在或分析未完成时抛出\n * \n * @example\n * ```typescript\n * const frames = await videoPsych.getFrames('analysis_123');\n * console.log(`共 ${frames.total} 帧`);\n * frames.items.forEach(item => {\n * console.log(`${item.timestamp}s: ${item.image_url}`);\n * if (item.vision_result) {\n * console.log(` 表情: ${item.vision_result.expression}`);\n * console.log(` 动作: ${item.vision_result.action}`);\n * }\n * });\n * ```\n */\n public async getFrames(id: string): Promise<FramesData> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/frames`);\n }\n\n /**\n * 获取段落分析结果\n * \n * @param id - 任务ID\n * @returns 段落分析数据\n * @throws {PlolinkError} 当任务不存在或分析未完成时抛出\n * \n * @example\n * ```typescript\n * const paragraphs = await videoPsych.getParagraphs('analysis_123');\n * console.log(`共 ${paragraphs.total} 段`);\n * paragraphs.items.forEach(item => {\n * console.log(`段落 ${item.id}:`);\n * console.log(` 时间: ${item.start_time}s - ${item.end_time}s`);\n * console.log(` 内容: ${item.text}`);\n * console.log(` 摘要: ${item.summary}`);\n * if (item.nlp_result) {\n * console.log(` 情绪: ${item.nlp_result.speaker_emotion}`);\n * console.log(` 态度: ${item.nlp_result.real_attitude}`);\n * }\n * });\n * ```\n */\n public async getParagraphs(id: string): Promise<ParagraphsData> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/paragraphs`);\n }\n}\n"]}
1
+ {"version":3,"sources":["../../../src/modules/video-psych-analysis/index.ts"],"names":["PlolinkError","Poller"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * 视频人物心理分析模块\n * \n * @description\n * 提供视频人物心理分析相关功能,包括:\n * - 创建分析任务\n * - 查询任务详情和状态\n * - 同步任务状态(轮询)\n * - 获取分析结果(文本/帧/段落维度)\n * - 生成心理分析报告\n * \n * @example\n * ```typescript\n * import { PlolinkClient } from '@plolink/sdk';\n * import { VideoPsychAnalysis } from '@plolink/sdk/video-psych-analysis';\n * \n * const client = new PlolinkClient({\n * mode: 'apiKey',\n * apiKey: 'your-api-key'\n * });\n * \n * const videoPsych = new VideoPsychAnalysis(client);\n * \n * // 创建分析任务\n * const result = await videoPsych.create({\n * name: '候选人A面试分析',\n * videoFileIds: ['file1', 'file2'],\n * referenceImageFileId: 'refImage1',\n * prompt: '视频是某公司 CEO 的公开演讲,请分析他对某话题的真实态度',\n * frameFps: 3,\n * language: 'zh-CN'\n * });\n * console.log(`任务已创建: ${result.id}`);\n * \n * // 轮询任务状态\n * const poller = videoPsych.watchAnalysisStatus(result.id, (detail) => {\n * console.log(`分析进度: ${detail.progress.done}/${detail.progress.total}`);\n * if (detail.status === 'COMPLETED') {\n * console.log('分析完成,报告已生成!');\n * console.log(detail.reportContent);\n * }\n * });\n * ```\n * \n * @module video-psych-analysis\n */\n\nimport { PlolinkClient } from '../../core/client';\nimport { Poller } from '../../common/poller';\nimport { PlolinkError } from '../../core/error';\nimport type {\n CreateVideoPsychAnalysisParams,\n CreateVideoPsychAnalysisResponse,\n VideoPsychAnalysisDetail,\n SyncStatusResponse,\n TextsData,\n FramesData,\n ParagraphsData,\n ListVideoPsychAnalysesParams,\n ListVideoPsychAnalysesResponse,\n UpdateVideoPsychAnalysisParams,\n UpdateVideoPsychAnalysisResponse,\n VideoPsychAnalysisConfig,\n} from '../../types/video-psych-analysis';\n\nexport type {\n VideoPsychAnalysisStatus,\n CreateVideoPsychAnalysisParams,\n VideoInfo,\n AnalysisProgress,\n FileInfo,\n CreateVideoPsychAnalysisResponse,\n VideoPsychAnalysisDetail,\n SyncStatusResponse,\n TextAnalysisItem,\n TextsData,\n FrameAnalysisItem,\n FramesData,\n ParagraphAnalysisItem,\n ParagraphsData,\n ListVideoPsychAnalysesParams,\n VideoPsychAnalysisSummary,\n ListVideoPsychAnalysesResponse,\n UpdateVideoPsychAnalysisParams,\n UpdateVideoPsychAnalysisResponse,\n LanguageOption,\n VideoPsychAnalysisConfig,\n} from '../../types/video-psych-analysis';\n\n/**\n * 视频人物心理分析模块\n */\nexport class VideoPsychAnalysis {\n private client: PlolinkClient;\n\n constructor(client: PlolinkClient) {\n this.client = client;\n }\n\n /**\n * 获取视频心理分析配置\n * \n * @returns 配置信息(包括语言选项等)\n * \n * @example\n * ```typescript\n * const config = await videoPsych.getConfig();\n * console.log('语言选项:', config.languageOptions);\n * console.log('默认语言:', config.defaultLanguage);\n * ```\n */\n public async getConfig(): Promise<VideoPsychAnalysisConfig> {\n return this.client.axiosInstance.get('/api/v1/video-psych-analysis/config');\n }\n\n /**\n * 查询分析任务列表\n * \n * @param params - 查询参数(可选)\n * @returns 任务列表\n * @throws {PlolinkError} 当查询失败时抛出\n * \n * @example\n * ```typescript\n * // 查询所有已完成的任务\n * const result = await videoPsych.list({\n * status: 'COMPLETED',\n * page: 1,\n * pageSize: 20\n * });\n * console.log(`共 ${result.total} 个任务`);\n * result.list.forEach(item => {\n * console.log(`${item.name}: ${item.status}`);\n * });\n * ```\n */\n public async list(params?: ListVideoPsychAnalysesParams): Promise<ListVideoPsychAnalysesResponse> {\n return this.client.axiosInstance.get('/api/v1/video-psych-analysis', { params });\n }\n\n /**\n * 创建视频心理分析任务\n * \n * @param params - 创建参数\n * @returns 创建结果,包含任务ID和初始状态\n * @throws {PlolinkError} 当参数验证失败或创建失败时抛出\n * \n * @example\n * ```typescript\n * const result = await videoPsych.create({\n * name: '候选人A面试分析',\n * videoFileIds: ['file1', 'file2', 'file3'],\n * referenceImageFileId: 'refImage1',\n * prompt: '请以专业心理分析师的视角,分析候选人的情绪、态度和心理状态',\n * frameFps: 3,\n * language: 'zh'\n * });\n * console.log(`任务ID: ${result.id}, 状态: ${result.status}`);\n * ```\n */\n public async create(params: CreateVideoPsychAnalysisParams): Promise<CreateVideoPsychAnalysisResponse> {\n const { videoFileIds, referenceImageFileId, prompt, familyBackground, frameFps, language, name } = params;\n\n // 参数验证\n if (!videoFileIds || videoFileIds.length === 0) {\n throw new PlolinkError('videoFileIds is required and must not be empty', 'INVALID_PARAMS');\n }\n\n if (!referenceImageFileId) {\n throw new PlolinkError('referenceImageFileId is required', 'INVALID_PARAMS');\n }\n\n if (!prompt) {\n throw new PlolinkError('prompt is required', 'INVALID_PARAMS');\n }\n\n if (frameFps !== undefined && (frameFps < 1 || frameFps > 30)) {\n throw new PlolinkError('frameFps must be between 1 and 30', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.post('/api/v1/video-psych-analysis', {\n name,\n videoFileIds,\n referenceImageFileId,\n prompt,\n familyBackground,\n frameFps,\n language,\n });\n }\n\n /**\n * 获取分析任务详情\n * \n * @param id - 任务ID\n * @returns 任务详情信息\n * @throws {PlolinkError} 当任务不存在或无权访问时抛出\n * \n * @example\n * ```typescript\n * const detail = await videoPsych.getDetail('analysis_123');\n * console.log(`任务: ${detail.name}`);\n * console.log(`状态: ${detail.status}`);\n * console.log(`进度: ${detail.progress.done}/${detail.progress.total}`);\n * \n * if (detail.reportContent) {\n * console.log('报告已生成');\n * }\n * ```\n */\n public async getDetail(id: string): Promise<VideoPsychAnalysisDetail> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}`);\n }\n\n /**\n * 获取视频元数据信息\n * \n * @description\n * 获取任务的视频元数据信息(videoInfo)。在异步模式下,任务创建时 videoInfo 为空,\n * 需要等待任务进入 PROCESSING 状态后由定时任务自动同步。\n * \n * **使用场景**:\n * - 获取视频的宽高、时长、编码等信息用于界面展示\n * - 在任务创建后轮询此接口直到获取到 videoInfo\n * \n * **注意**:\n * - 如果视频信息尚未生成,返回 null\n * - 建议配合任务状态查询使用,等待状态变为 PROCESSING 后再查询\n * \n * @param id - 任务ID\n * @returns 视频元数据信息,如果尚未生成则返回 null\n * @throws {PlolinkError} 当任务不存在时抛出\n * \n * @example\n * ```typescript\n * // 轮询获取 videoInfo\n * const checkVideoInfo = async (analysisId: string) => {\n * const maxAttempts = 60;\n * let attempt = 0;\n * \n * while (attempt < maxAttempts) {\n * const videoInfo = await videoPsych.getVideoInfo(analysisId);\n * \n * if (videoInfo) {\n * console.log(`视频信息: ${videoInfo.width}x${videoInfo.height}`);\n * console.log(`时长: ${videoInfo.duration}s`);\n * console.log(`文件大小: ${(videoInfo.file_size / 1024 / 1024).toFixed(2)}MB`);\n * return videoInfo;\n * }\n * \n * console.log('视频信息还在处理中...');\n * await new Promise(resolve => setTimeout(resolve, 5000)); // 等待5秒\n * attempt++;\n * }\n * \n * throw new Error('获取视频信息超时');\n * };\n * \n * const info = await checkVideoInfo('analysis_123');\n * ```\n */\n public async getVideoInfo(id: string): Promise<import('../../types/video-psych-analysis').VideoInfo | null> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n try {\n const response: { taskId: string; videoInfo: import('../../types/video-psych-analysis').VideoInfo | null } = await this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/video-info`);\n return response.videoInfo || null;\n } catch (error: unknown) {\n // 如果是 PlolinkError 且 HTTP 状态码为 404(视频信息尚未生成),返回 null\n // 注意:axios interceptor 会将 HTTP 状态码作为 PlolinkError.code\n if (error instanceof PlolinkError && error.code === 404) {\n return null;\n }\n // 其他错误继续抛出\n throw error;\n }\n }\n\n /**\n * 更新分析任务\n * \n * @description\n * 更新分析任务的基本信息(仅限 PENDING 和 FAILED 状态的任务)。\n * \n * @param id - 任务ID\n * @param params - 更新参数\n * @returns 更新后的任务信息\n * @throws {PlolinkError} 当任务不存在、状态不允许更新或更新失败时抛出\n * \n * @example\n * ```typescript\n * const updated = await videoPsych.update('analysis_123', {\n * name: '李四的心理分析',\n * prompt: '请以临床心理学专家的视角进行分析'\n * });\n * console.log(`已更新: ${updated.name}`);\n * ```\n */\n public async update(id: string, params: UpdateVideoPsychAnalysisParams): Promise<UpdateVideoPsychAnalysisResponse> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n if (!params.name && !params.prompt && !params.familyBackground) {\n throw new PlolinkError('At least one field (name, prompt, or familyBackground) must be provided', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.patch(`/api/v1/video-psych-analysis/${id}`, params);\n }\n\n /**\n * 删除分析任务\n * \n * @description\n * 删除分析任务(软删除)。\n * \n * @param id - 任务ID\n * @throws {PlolinkError} 当任务不存在或删除失败时抛出\n * \n * @example\n * ```typescript\n * await videoPsych.delete('analysis_123');\n * console.log('任务已删除');\n * ```\n */\n public async delete(id: string): Promise<{ message: string }> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.delete(`/api/v1/video-psych-analysis/${id}`);\n }\n\n /**\n * 重试失败的分析任务\n * \n * @description\n * 对失败(FAILED)状态的任务进行重试,使用原有参数重新提交到AI引擎进行分析。\n * 重试会清空之前的错误信息和分析结果,重新开始完整的分析流程。\n * \n * **注意**:\n * - 只能重试状态为 FAILED 的任务\n * - 重试后任务状态会重置为 PENDING\n * - 会清空之前的分析结果和报告内容\n * - 建议配合 `watchAnalysisStatus()` 方法监听重试后的任务状态\n * \n * @param id - 任务ID\n * @returns 更新后的任务信息\n * @throws {PlolinkError} 当任务不存在、状态不是FAILED或重试失败时抛出\n * \n * @example\n * ```typescript\n * // 重试失败的任务\n * const result = await videoPsych.retry('analysis_123');\n * console.log(`任务已重新提交: ${result.id}`);\n * console.log(`当前状态: ${result.status}`);\n * \n * // 监听重试后的任务状态\n * const poller = videoPsych.watchAnalysisStatus(result.id, (detail) => {\n * console.log(`重试进度: ${detail.progress.done}/${detail.progress.total}`);\n * if (detail.status === 'COMPLETED') {\n * console.log('重试成功,分析完成!');\n * } else if (detail.status === 'FAILED') {\n * console.error('重试后仍失败');\n * }\n * });\n * poller.start();\n * ```\n */\n public async retry(id: string): Promise<VideoPsychAnalysisDetail> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.post(`/api/v1/video-psych-analysis/${id}/retry`);\n }\n\n /**\n * 同步任务状态\n * \n * @description\n * 主动触发后端从 AI TOOLS API 同步最新状态和中间结果。\n * \n * **注意**:通常不需要手动调用此方法,系统会每30秒自动轮询同步所有非完成态的任务。\n * \n * @param id - 任务ID\n * @returns 同步后的状态信息\n * @throws {PlolinkError} 当任务不存在或同步失败时抛出\n * \n * @example\n * ```typescript\n * const status = await videoPsych.syncStatus('analysis_123');\n * console.log(`当前状态: ${status.status}`);\n * console.log(`进度: ${status.progress.done}/${status.progress.total}`);\n * ```\n */\n public async syncStatus(id: string): Promise<SyncStatusResponse> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/status`);\n }\n\n /**\n * 轮询分析任务状态\n * \n * @description\n * 创建一个轮询器持续监听任务状态变化,直到任务达到终态(COMPLETED/FAILED)。\n * 使用指数退避策略,初始间隔5秒,最大间隔30秒。\n * \n * @param id - 任务ID\n * @param onStatusChange - 状态变化回调函数\n * @returns Poller实例,可用于手动停止轮询\n * \n * @example\n * ```typescript\n * const poller = videoPsych.watchAnalysisStatus('analysis_123', (detail) => {\n * console.log(`状态: ${detail.status}`);\n * console.log(`进度: ${detail.progress.done}/${detail.progress.total} (${detail.progress.stage})`);\n * \n * if (detail.status === 'COMPLETED') {\n * console.log('分析完成,报告已生成!');\n * console.log(detail.reportContent);\n * } else if (detail.status === 'FAILED') {\n * console.error(`分析失败: ${detail.errorMessage}`);\n * }\n * });\n * \n * // 开始轮询\n * poller.start();\n * \n * // 需要时可以手动停止\n * // poller.stop();\n * ```\n */\n public watchAnalysisStatus(\n id: string,\n onStatusChange: (detail: VideoPsychAnalysisDetail) => void\n ): Poller<VideoPsychAnalysisDetail> {\n const poller = new Poller<VideoPsychAnalysisDetail>({\n task: async () => {\n // 先同步状态,再获取详情\n await this.syncStatus(id);\n return this.getDetail(id);\n },\n onResult: onStatusChange,\n shouldStop: (detail) => {\n return ['COMPLETED', 'FAILED'].includes(detail.status);\n },\n initialInterval: 5000, // 5秒\n maxInterval: 30000, // 30秒\n backoffFactor: 1.5,\n onError: (error) => {\n this.client.logger.error('Analysis polling error', { error, id });\n },\n });\n\n // 自动启动\n void poller.start();\n\n return poller;\n }\n\n /**\n * 获取文本维度分析结果\n * \n * @param id - 任务ID\n * @returns 文本维度分析数据\n * @throws {PlolinkError} 当任务不存在或分析未完成时抛出\n * \n * @example\n * ```typescript\n * const texts = await videoPsych.getTexts('analysis_123');\n * console.log(`共 ${texts.total} 条文本`);\n * texts.items.forEach(item => {\n * console.log(`${item.start_time}s: ${item.text}`);\n * if (item.nlp_result) {\n * console.log(` 情绪: ${item.nlp_result.speaker_emotion}`);\n * console.log(` 态度: ${item.nlp_result.real_attitude}`);\n * }\n * });\n * ```\n */\n public async getTexts(id: string): Promise<TextsData> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/texts`);\n }\n\n /**\n * 获取帧维度分析结果\n * \n * @param id - 任务ID\n * @returns 帧维度分析数据\n * @throws {PlolinkError} 当任务不存在或分析未完成时抛出\n * \n * @example\n * ```typescript\n * const frames = await videoPsych.getFrames('analysis_123');\n * console.log(`共 ${frames.total} 帧`);\n * frames.items.forEach(item => {\n * console.log(`${item.timestamp}s: ${item.image_url}`);\n * if (item.vision_result) {\n * console.log(` 表情: ${item.vision_result.expression}`);\n * console.log(` 动作: ${item.vision_result.action}`);\n * }\n * });\n * ```\n */\n public async getFrames(id: string): Promise<FramesData> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/frames`);\n }\n\n /**\n * 获取段落分析结果\n * \n * @param id - 任务ID\n * @returns 段落分析数据\n * @throws {PlolinkError} 当任务不存在或分析未完成时抛出\n * \n * @example\n * ```typescript\n * const paragraphs = await videoPsych.getParagraphs('analysis_123');\n * console.log(`共 ${paragraphs.total} 段`);\n * paragraphs.items.forEach(item => {\n * console.log(`段落 ${item.id}:`);\n * console.log(` 时间: ${item.start_time}s - ${item.end_time}s`);\n * console.log(` 内容: ${item.text}`);\n * console.log(` 摘要: ${item.summary}`);\n * if (item.nlp_result) {\n * console.log(` 情绪: ${item.nlp_result.speaker_emotion}`);\n * console.log(` 态度: ${item.nlp_result.real_attitude}`);\n * }\n * });\n * ```\n */\n public async getParagraphs(id: string): Promise<ParagraphsData> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/paragraphs`);\n }\n}\n"]}