v2er-insight 1.0.0
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.
- package/README.md +215 -0
- package/dist/cli/commands/ai.d.ts +13 -0
- package/dist/cli/commands/ai.js +153 -0
- package/dist/cli/commands/analyze.d.ts +13 -0
- package/dist/cli/commands/analyze.js +80 -0
- package/dist/cli/commands/config.d.ts +43 -0
- package/dist/cli/commands/config.js +267 -0
- package/dist/cli/commands/fetch.d.ts +13 -0
- package/dist/cli/commands/fetch.js +150 -0
- package/dist/cli/commands/index.d.ts +10 -0
- package/dist/cli/commands/index.js +22 -0
- package/dist/cli/commands/run.d.ts +23 -0
- package/dist/cli/commands/run.js +52 -0
- package/dist/cli/commands/show.d.ts +13 -0
- package/dist/cli/commands/show.js +154 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.js +107 -0
- package/dist/cli/types.d.ts +58 -0
- package/dist/cli/types.js +6 -0
- package/dist/cli/utils/error.d.ts +6 -0
- package/dist/cli/utils/error.js +18 -0
- package/dist/cli/utils.d.ts +20 -0
- package/dist/cli/utils.js +48 -0
- package/dist/cli/workflow/orchestrator.d.ts +15 -0
- package/dist/cli/workflow/orchestrator.js +144 -0
- package/dist/cli/workflow/recovery.d.ts +10 -0
- package/dist/cli/workflow/recovery.js +134 -0
- package/dist/cli/workflow/state.d.ts +19 -0
- package/dist/cli/workflow/state.js +45 -0
- package/dist/cli/workflow/types.d.ts +60 -0
- package/dist/cli/workflow/types.js +3 -0
- package/dist/config/defaults.d.ts +48 -0
- package/dist/config/defaults.js +42 -0
- package/dist/config/index.d.ts +16 -0
- package/dist/config/index.js +21 -0
- package/dist/config/path.d.ts +11 -0
- package/dist/config/path.js +28 -0
- package/dist/config/proxy.d.ts +16 -0
- package/dist/config/proxy.js +39 -0
- package/dist/config/storage.d.ts +23 -0
- package/dist/config/storage.js +85 -0
- package/dist/config/types/ai.d.ts +31 -0
- package/dist/config/types/ai.js +13 -0
- package/dist/config/types/analyzer.d.ts +15 -0
- package/dist/config/types/analyzer.js +6 -0
- package/dist/config/types/data.d.ts +20 -0
- package/dist/config/types/data.js +6 -0
- package/dist/config/types/fetch.d.ts +9 -0
- package/dist/config/types/fetch.js +6 -0
- package/dist/config/types/index.d.ts +32 -0
- package/dist/config/types/index.js +11 -0
- package/dist/config/types/log.d.ts +11 -0
- package/dist/config/types/log.js +6 -0
- package/dist/core/ai/index.d.ts +11 -0
- package/dist/core/ai/index.js +18 -0
- package/dist/core/ai/parser/index.d.ts +12 -0
- package/dist/core/ai/parser/index.js +44 -0
- package/dist/core/ai/parser/validator.d.ts +18 -0
- package/dist/core/ai/parser/validator.js +179 -0
- package/dist/core/ai/prompt/index.d.ts +20 -0
- package/dist/core/ai/prompt/index.js +75 -0
- package/dist/core/ai/prompt/system-prompt.md +210 -0
- package/dist/core/ai/providers/gemini.d.ts +25 -0
- package/dist/core/ai/providers/gemini.js +74 -0
- package/dist/core/ai/providers/index.d.ts +6 -0
- package/dist/core/ai/providers/index.js +9 -0
- package/dist/core/ai/types/index.d.ts +7 -0
- package/dist/core/ai/types/index.js +6 -0
- package/dist/core/ai/types/options.d.ts +14 -0
- package/dist/core/ai/types/options.js +6 -0
- package/dist/core/ai/types/provider.d.ts +19 -0
- package/dist/core/ai/types/provider.js +6 -0
- package/dist/core/ai/types/result.d.ts +64 -0
- package/dist/core/ai/types/result.js +6 -0
- package/dist/core/ai/utils/api-key.d.ts +15 -0
- package/dist/core/ai/utils/api-key.js +36 -0
- package/dist/core/ai/utils/index.d.ts +6 -0
- package/dist/core/ai/utils/index.js +11 -0
- package/dist/core/ai/utils/retry.d.ts +15 -0
- package/dist/core/ai/utils/retry.js +37 -0
- package/dist/core/analyzer/builder.d.ts +23 -0
- package/dist/core/analyzer/builder.js +113 -0
- package/dist/core/analyzer/content/chunker.d.ts +18 -0
- package/dist/core/analyzer/content/chunker.js +74 -0
- package/dist/core/analyzer/content/index.d.ts +7 -0
- package/dist/core/analyzer/content/index.js +13 -0
- package/dist/core/analyzer/content/transformer.d.ts +19 -0
- package/dist/core/analyzer/content/transformer.js +33 -0
- package/dist/core/analyzer/index.d.ts +17 -0
- package/dist/core/analyzer/index.js +21 -0
- package/dist/core/analyzer/periods/detector.d.ts +17 -0
- package/dist/core/analyzer/periods/detector.js +36 -0
- package/dist/core/analyzer/periods/index.d.ts +6 -0
- package/dist/core/analyzer/periods/index.js +11 -0
- package/dist/core/analyzer/periods/splitter.d.ts +11 -0
- package/dist/core/analyzer/periods/splitter.js +35 -0
- package/dist/core/analyzer/stats/index.d.ts +7 -0
- package/dist/core/analyzer/stats/index.js +13 -0
- package/dist/core/analyzer/stats/reply-stats.d.ts +15 -0
- package/dist/core/analyzer/stats/reply-stats.js +45 -0
- package/dist/core/analyzer/stats/topic-stats.d.ts +16 -0
- package/dist/core/analyzer/stats/topic-stats.js +51 -0
- package/dist/core/analyzer/stats/user-overview.d.ts +9 -0
- package/dist/core/analyzer/stats/user-overview.js +52 -0
- package/dist/core/analyzer/types/index.d.ts +7 -0
- package/dist/core/analyzer/types/index.js +6 -0
- package/dist/core/analyzer/types/input.d.ts +13 -0
- package/dist/core/analyzer/types/input.js +6 -0
- package/dist/core/analyzer/types/internal.d.ts +28 -0
- package/dist/core/analyzer/types/internal.js +6 -0
- package/dist/core/analyzer/types/output.d.ts +68 -0
- package/dist/core/analyzer/types/output.js +6 -0
- package/dist/core/analyzer/utils/date-parser.d.ts +41 -0
- package/dist/core/analyzer/utils/date-parser.js +118 -0
- package/dist/core/analyzer/utils/index.d.ts +6 -0
- package/dist/core/analyzer/utils/index.js +18 -0
- package/dist/core/analyzer/utils/stats.d.ts +12 -0
- package/dist/core/analyzer/utils/stats.js +64 -0
- package/dist/core/v2ex/index.d.ts +10 -0
- package/dist/core/v2ex/index.js +27 -0
- package/dist/core/v2ex/parsers/index.d.ts +8 -0
- package/dist/core/v2ex/parsers/index.js +15 -0
- package/dist/core/v2ex/parsers/replies-page.d.ts +11 -0
- package/dist/core/v2ex/parsers/replies-page.js +114 -0
- package/dist/core/v2ex/parsers/selectors/index.d.ts +10 -0
- package/dist/core/v2ex/parsers/selectors/index.js +18 -0
- package/dist/core/v2ex/parsers/selectors/pagination.d.ts +11 -0
- package/dist/core/v2ex/parsers/selectors/pagination.js +14 -0
- package/dist/core/v2ex/parsers/selectors/replies-page.d.ts +21 -0
- package/dist/core/v2ex/parsers/selectors/replies-page.js +24 -0
- package/dist/core/v2ex/parsers/selectors/topic-detail.d.ts +19 -0
- package/dist/core/v2ex/parsers/selectors/topic-detail.js +22 -0
- package/dist/core/v2ex/parsers/selectors/topics-list-page.d.ts +11 -0
- package/dist/core/v2ex/parsers/selectors/topics-list-page.js +14 -0
- package/dist/core/v2ex/parsers/selectors/user-profile.d.ts +11 -0
- package/dist/core/v2ex/parsers/selectors/user-profile.js +14 -0
- package/dist/core/v2ex/parsers/topic-detail.d.ts +11 -0
- package/dist/core/v2ex/parsers/topic-detail.js +94 -0
- package/dist/core/v2ex/parsers/topics-list-page.d.ts +11 -0
- package/dist/core/v2ex/parsers/topics-list-page.js +90 -0
- package/dist/core/v2ex/parsers/user-profile.d.ts +11 -0
- package/dist/core/v2ex/parsers/user-profile.js +70 -0
- package/dist/core/v2ex/parsers/utils/index.d.ts +6 -0
- package/dist/core/v2ex/parsers/utils/index.js +9 -0
- package/dist/core/v2ex/parsers/utils/pagination.d.ts +19 -0
- package/dist/core/v2ex/parsers/utils/pagination.js +29 -0
- package/dist/core/v2ex/types/entities.d.ts +45 -0
- package/dist/core/v2ex/types/entities.js +7 -0
- package/dist/core/v2ex/types/index.d.ts +6 -0
- package/dist/core/v2ex/types/index.js +6 -0
- package/dist/core/v2ex/types/parse-result.d.ts +64 -0
- package/dist/core/v2ex/types/parse-result.js +7 -0
- package/dist/core/v2ex/urls/constants.d.ts +5 -0
- package/dist/core/v2ex/urls/constants.js +8 -0
- package/dist/core/v2ex/urls/index.d.ts +7 -0
- package/dist/core/v2ex/urls/index.js +16 -0
- package/dist/core/v2ex/urls/topic-urls.d.ts +19 -0
- package/dist/core/v2ex/urls/topic-urls.js +48 -0
- package/dist/core/v2ex/urls/user-urls.d.ts +24 -0
- package/dist/core/v2ex/urls/user-urls.js +36 -0
- package/dist/core/v2ex/use-cases/index.d.ts +8 -0
- package/dist/core/v2ex/use-cases/index.js +14 -0
- package/dist/core/v2ex/use-cases/types.d.ts +31 -0
- package/dist/core/v2ex/use-cases/types.js +7 -0
- package/dist/core/v2ex/use-cases/user/index.d.ts +10 -0
- package/dist/core/v2ex/use-cases/user/index.js +16 -0
- package/dist/core/v2ex/use-cases/user/profile.d.ts +14 -0
- package/dist/core/v2ex/use-cases/user/profile.js +51 -0
- package/dist/core/v2ex/use-cases/user/replies.d.ts +14 -0
- package/dist/core/v2ex/use-cases/user/replies.js +20 -0
- package/dist/core/v2ex/use-cases/user/topic-urls.d.ts +21 -0
- package/dist/core/v2ex/use-cases/user/topic-urls.js +29 -0
- package/dist/core/v2ex/use-cases/user/topics-detail.d.ts +30 -0
- package/dist/core/v2ex/use-cases/user/topics-detail.js +62 -0
- package/dist/core/v2ex/use-cases/utils/index.d.ts +6 -0
- package/dist/core/v2ex/use-cases/utils/index.js +9 -0
- package/dist/core/v2ex/use-cases/utils/page-orchestrator.d.ts +24 -0
- package/dist/core/v2ex/use-cases/utils/page-orchestrator.js +93 -0
- package/dist/infra/fetcher/agent.d.ts +10 -0
- package/dist/infra/fetcher/agent.js +17 -0
- package/dist/infra/fetcher/fetcher.d.ts +10 -0
- package/dist/infra/fetcher/fetcher.js +81 -0
- package/dist/infra/fetcher/index.d.ts +3 -0
- package/dist/infra/fetcher/index.js +19 -0
- package/dist/infra/fetcher/types.d.ts +29 -0
- package/dist/infra/fetcher/types.js +6 -0
- package/dist/infra/logger/colors.d.ts +15 -0
- package/dist/infra/logger/colors.js +18 -0
- package/dist/infra/logger/index.d.ts +16 -0
- package/dist/infra/logger/index.js +19 -0
- package/dist/infra/logger/logger.d.ts +34 -0
- package/dist/infra/logger/logger.js +101 -0
- package/dist/infra/storage/cleaner.d.ts +24 -0
- package/dist/infra/storage/cleaner.js +73 -0
- package/dist/infra/storage/index.d.ts +7 -0
- package/dist/infra/storage/index.js +15 -0
- package/dist/infra/storage/paths.d.ts +26 -0
- package/dist/infra/storage/paths.js +53 -0
- package/dist/infra/storage/reader.d.ts +15 -0
- package/dist/infra/storage/reader.js +34 -0
- package/dist/infra/storage/types.d.ts +21 -0
- package/dist/infra/storage/types.js +18 -0
- package/dist/infra/storage/writer.d.ts +16 -0
- package/dist/infra/storage/writer.js +31 -0
- package/package.json +89 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 数据管理配置类型
|
|
3
|
+
*/
|
|
4
|
+
/** 数据管理配置 */
|
|
5
|
+
export interface DataConfig {
|
|
6
|
+
/**
|
|
7
|
+
* AI 成功后是否永久保留原始数据(raw.json / analyzed.json)
|
|
8
|
+
* - true:永久保留,不自动清理
|
|
9
|
+
* - false:按 rawRetention 天数自动清理(默认)
|
|
10
|
+
*/
|
|
11
|
+
keepRaw?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* 原始数据保留天数(仅 keepRaw=false 时生效)
|
|
14
|
+
* 超过此天数的 raw.json / analyzed.json 会被自动清理
|
|
15
|
+
* result.json 永远不会被清理
|
|
16
|
+
* 有效范围:>= 0(0 表示不保留,负数会被修正为 0)
|
|
17
|
+
*/
|
|
18
|
+
rawRetention?: number;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=data.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 配置类型 — 统一导出
|
|
3
|
+
*
|
|
4
|
+
* 每个模块的配置拆分为独立文件,方便阅读和按需引用。
|
|
5
|
+
*/
|
|
6
|
+
export type { AIConfig, ThinkingLevel } from './ai';
|
|
7
|
+
export { THINKING_LEVELS } from './ai';
|
|
8
|
+
export type { FetchConfig } from './fetch';
|
|
9
|
+
export type { AnalyzerConfig } from './analyzer';
|
|
10
|
+
export type { DataConfig } from './data';
|
|
11
|
+
export type { LogConfig, LogLevel } from './log';
|
|
12
|
+
import type { AIConfig } from './ai';
|
|
13
|
+
import type { FetchConfig } from './fetch';
|
|
14
|
+
import type { AnalyzerConfig } from './analyzer';
|
|
15
|
+
import type { DataConfig } from './data';
|
|
16
|
+
import type { LogConfig } from './log';
|
|
17
|
+
/** 全局配置接口 */
|
|
18
|
+
export interface V2erConfig {
|
|
19
|
+
/** 代理服务器地址(如 http://127.0.0.1:10808) */
|
|
20
|
+
proxy?: string;
|
|
21
|
+
/** AI 模块配置 */
|
|
22
|
+
ai?: AIConfig;
|
|
23
|
+
/** Fetcher 模块配置 */
|
|
24
|
+
fetch?: FetchConfig;
|
|
25
|
+
/** Analyzer 模块配置 */
|
|
26
|
+
analyzer?: AnalyzerConfig;
|
|
27
|
+
/** 数据管理配置 */
|
|
28
|
+
data?: DataConfig;
|
|
29
|
+
/** 日志配置 */
|
|
30
|
+
log?: LogConfig;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 配置类型 — 统一导出
|
|
4
|
+
*
|
|
5
|
+
* 每个模块的配置拆分为独立文件,方便阅读和按需引用。
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.THINKING_LEVELS = void 0;
|
|
9
|
+
var ai_1 = require("./ai");
|
|
10
|
+
Object.defineProperty(exports, "THINKING_LEVELS", { enumerable: true, get: function () { return ai_1.THINKING_LEVELS; } });
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI 模块入口
|
|
3
|
+
*
|
|
4
|
+
* 提供用户分析功能的统一接口
|
|
5
|
+
*/
|
|
6
|
+
export type { AIAnalysisInput, AIAnalysisResult, AnalysisOptions, IAIProvider, SessionOptions, ProfessionalProfile, PersonalProfile, PsychologicalProfile, BehavioralProfile, SocialProfile, RiskAssessment, } from './types';
|
|
7
|
+
export { GeminiProvider } from './providers';
|
|
8
|
+
export { parseResponse, type ValidationResult } from './parser';
|
|
9
|
+
export { resolveApiKey, withRetry, type RetryOptions } from './utils';
|
|
10
|
+
export { buildMessageSequence, type MessageSequence } from './prompt';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AI 模块入口
|
|
4
|
+
*
|
|
5
|
+
* 提供用户分析功能的统一接口
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.buildMessageSequence = exports.withRetry = exports.resolveApiKey = exports.parseResponse = exports.GeminiProvider = void 0;
|
|
9
|
+
var providers_1 = require("./providers");
|
|
10
|
+
Object.defineProperty(exports, "GeminiProvider", { enumerable: true, get: function () { return providers_1.GeminiProvider; } });
|
|
11
|
+
var parser_1 = require("./parser");
|
|
12
|
+
Object.defineProperty(exports, "parseResponse", { enumerable: true, get: function () { return parser_1.parseResponse; } });
|
|
13
|
+
var utils_1 = require("./utils");
|
|
14
|
+
Object.defineProperty(exports, "resolveApiKey", { enumerable: true, get: function () { return utils_1.resolveApiKey; } });
|
|
15
|
+
Object.defineProperty(exports, "withRetry", { enumerable: true, get: function () { return utils_1.withRetry; } });
|
|
16
|
+
var prompt_1 = require("./prompt");
|
|
17
|
+
Object.defineProperty(exports, "buildMessageSequence", { enumerable: true, get: function () { return prompt_1.buildMessageSequence; } });
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI 响应解析器
|
|
3
|
+
*/
|
|
4
|
+
import { type ValidationResult } from './validator';
|
|
5
|
+
export type { ValidationResult };
|
|
6
|
+
/**
|
|
7
|
+
* 将 AI 响应文本解析为 AIAnalysisResult
|
|
8
|
+
*
|
|
9
|
+
* 返回 ValidationResult,包含 data 和 warnings
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseResponse(rawText: string): ValidationResult;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AI 响应解析器
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseResponse = parseResponse;
|
|
7
|
+
const validator_1 = require("./validator");
|
|
8
|
+
/**
|
|
9
|
+
* 如果存在 Markdown 代码块,从中提取 JSON
|
|
10
|
+
*
|
|
11
|
+
* 优先匹配 ```json 标记的代码块,其次匹配无标记代码块
|
|
12
|
+
*/
|
|
13
|
+
function extractJson(text) {
|
|
14
|
+
const jsonBlockMatch = text.match(/```json\s*([\s\S]*?)```/);
|
|
15
|
+
if (jsonBlockMatch && jsonBlockMatch[1]) {
|
|
16
|
+
return jsonBlockMatch[1].trim();
|
|
17
|
+
}
|
|
18
|
+
const codeBlockMatch = text.match(/```\s*([\s\S]*?)```/);
|
|
19
|
+
if (codeBlockMatch && codeBlockMatch[1]) {
|
|
20
|
+
return codeBlockMatch[1].trim();
|
|
21
|
+
}
|
|
22
|
+
return text.trim();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 将 AI 响应文本解析为 AIAnalysisResult
|
|
26
|
+
*
|
|
27
|
+
* 返回 ValidationResult,包含 data 和 warnings
|
|
28
|
+
*/
|
|
29
|
+
function parseResponse(rawText) {
|
|
30
|
+
const jsonStr = extractJson(rawText);
|
|
31
|
+
let parsed;
|
|
32
|
+
try {
|
|
33
|
+
parsed = JSON.parse(jsonStr);
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
// JSON 解析失败,返回默认值和警告
|
|
37
|
+
return {
|
|
38
|
+
data: (0, validator_1.validateResponse)(null).data,
|
|
39
|
+
warnings: [`JSON 解析失败: ${e instanceof Error ? e.message : '未知错误'}`],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return (0, validator_1.validateResponse)(parsed);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI 响应 Schema 验证器 - 宽松模式
|
|
3
|
+
*
|
|
4
|
+
* 不抛出错误,缺失字段用默认值填充,返回警告列表
|
|
5
|
+
*/
|
|
6
|
+
import type { AIAnalysisResult } from '../types';
|
|
7
|
+
/** 验证结果 */
|
|
8
|
+
export interface ValidationResult {
|
|
9
|
+
data: AIAnalysisResult;
|
|
10
|
+
warnings: string[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 宽松验证 AI 响应
|
|
14
|
+
*
|
|
15
|
+
* 缺失字段用默认值填充,不抛出错误
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateResponse(data: unknown): ValidationResult;
|
|
18
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AI 响应 Schema 验证器 - 宽松模式
|
|
4
|
+
*
|
|
5
|
+
* 不抛出错误,缺失字段用默认值填充,返回警告列表
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.validateResponse = validateResponse;
|
|
9
|
+
const DEFAULT_SCORES = {
|
|
10
|
+
openness: 50,
|
|
11
|
+
conscientiousness: 50,
|
|
12
|
+
extraversion: 50,
|
|
13
|
+
agreeableness: 50,
|
|
14
|
+
neuroticism: 50,
|
|
15
|
+
};
|
|
16
|
+
const DEFAULT_RESULT = {
|
|
17
|
+
summary: '数据缺失,无法生成摘要',
|
|
18
|
+
professional: {
|
|
19
|
+
tech_stack: [],
|
|
20
|
+
career_path: '未知',
|
|
21
|
+
level: '未知',
|
|
22
|
+
focus_coherence: '未知',
|
|
23
|
+
evolution: {
|
|
24
|
+
summary: '未知',
|
|
25
|
+
timeline: [],
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
personal: {
|
|
29
|
+
hobbies: [],
|
|
30
|
+
life_stage: '未知',
|
|
31
|
+
values: [],
|
|
32
|
+
},
|
|
33
|
+
psychological: {
|
|
34
|
+
scores: DEFAULT_SCORES,
|
|
35
|
+
keywords: [],
|
|
36
|
+
},
|
|
37
|
+
behavioral: {
|
|
38
|
+
role: '未知',
|
|
39
|
+
interaction_style: '未知',
|
|
40
|
+
active_pattern: '未知',
|
|
41
|
+
heat_sensitivity: '未知',
|
|
42
|
+
},
|
|
43
|
+
social: {
|
|
44
|
+
content_appeal: '未知',
|
|
45
|
+
discussion_depth: '未知',
|
|
46
|
+
},
|
|
47
|
+
risk: {
|
|
48
|
+
level: 'safe',
|
|
49
|
+
reason: '数据不足,默认安全',
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
const RISK_LEVELS = ['safe', 'suspicious', 'high_risk'];
|
|
53
|
+
/**
|
|
54
|
+
* 宽松验证 AI 响应
|
|
55
|
+
*
|
|
56
|
+
* 缺失字段用默认值填充,不抛出错误
|
|
57
|
+
*/
|
|
58
|
+
function validateResponse(data) {
|
|
59
|
+
const warnings = [];
|
|
60
|
+
if (!data || typeof data !== 'object') {
|
|
61
|
+
warnings.push('响应不是有效对象,使用默认值');
|
|
62
|
+
return { data: structuredClone(DEFAULT_RESULT), warnings };
|
|
63
|
+
}
|
|
64
|
+
const obj = data;
|
|
65
|
+
const result = structuredClone(DEFAULT_RESULT);
|
|
66
|
+
// summary
|
|
67
|
+
if (typeof obj.summary === 'string') {
|
|
68
|
+
result.summary = obj.summary;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
warnings.push('缺少 summary 字段');
|
|
72
|
+
}
|
|
73
|
+
// professional
|
|
74
|
+
if (obj.professional && typeof obj.professional === 'object') {
|
|
75
|
+
result.professional = mergeWithDefault(obj.professional, DEFAULT_RESULT.professional);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
warnings.push('缺少 professional 字段');
|
|
79
|
+
}
|
|
80
|
+
// personal
|
|
81
|
+
if (obj.personal && typeof obj.personal === 'object') {
|
|
82
|
+
result.personal = mergeWithDefault(obj.personal, DEFAULT_RESULT.personal);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
warnings.push('缺少 personal 字段');
|
|
86
|
+
}
|
|
87
|
+
// psychological
|
|
88
|
+
if (obj.psychological && typeof obj.psychological === 'object') {
|
|
89
|
+
const psych = obj.psychological;
|
|
90
|
+
result.psychological = {
|
|
91
|
+
scores: validateScores(psych.scores, warnings),
|
|
92
|
+
keywords: Array.isArray(psych.keywords) ? psych.keywords : [],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
warnings.push('缺少 psychological 字段');
|
|
97
|
+
}
|
|
98
|
+
// behavioral
|
|
99
|
+
if (obj.behavioral && typeof obj.behavioral === 'object') {
|
|
100
|
+
result.behavioral = mergeWithDefault(obj.behavioral, DEFAULT_RESULT.behavioral);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
warnings.push('缺少 behavioral 字段');
|
|
104
|
+
}
|
|
105
|
+
// social
|
|
106
|
+
if (obj.social && typeof obj.social === 'object') {
|
|
107
|
+
result.social = mergeWithDefault(obj.social, DEFAULT_RESULT.social);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
warnings.push('缺少 social 字段');
|
|
111
|
+
}
|
|
112
|
+
// risk
|
|
113
|
+
if (obj.risk && typeof obj.risk === 'object') {
|
|
114
|
+
const risk = obj.risk;
|
|
115
|
+
const isValidLevel = RISK_LEVELS.includes(risk.level);
|
|
116
|
+
result.risk = {
|
|
117
|
+
level: isValidLevel ? risk.level : 'safe',
|
|
118
|
+
reason: typeof risk.reason === 'string' ? risk.reason : '未知',
|
|
119
|
+
};
|
|
120
|
+
if (!isValidLevel) {
|
|
121
|
+
warnings.push(`无效的 risk.level: ${risk.level},使用默认值 safe`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
warnings.push('缺少 risk 字段');
|
|
126
|
+
}
|
|
127
|
+
return { data: result, warnings };
|
|
128
|
+
}
|
|
129
|
+
/** 验证心理评分,值限制在 0-100 范围 */
|
|
130
|
+
function validateScores(scores, warnings) {
|
|
131
|
+
if (!scores || typeof scores !== 'object') {
|
|
132
|
+
warnings.push('缺少 psychological.scores');
|
|
133
|
+
return { ...DEFAULT_SCORES };
|
|
134
|
+
}
|
|
135
|
+
const s = scores;
|
|
136
|
+
const result = { ...DEFAULT_SCORES };
|
|
137
|
+
for (const key of Object.keys(DEFAULT_SCORES)) {
|
|
138
|
+
if (typeof s[key] === 'number') {
|
|
139
|
+
const raw = s[key];
|
|
140
|
+
const clamped = Math.max(0, Math.min(100, raw));
|
|
141
|
+
if (raw !== clamped) {
|
|
142
|
+
warnings.push(`psychological.scores.${key} 值 ${raw} 超出范围,已限制为 ${clamped}`);
|
|
143
|
+
}
|
|
144
|
+
result[key] = clamped;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
warnings.push(`缺少 psychological.scores.${key},使用默认值 50`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
/** 深度合并对象,缺失字段用默认值 */
|
|
153
|
+
function mergeWithDefault(source, defaults) {
|
|
154
|
+
if (!source || typeof source !== 'object') {
|
|
155
|
+
return defaults;
|
|
156
|
+
}
|
|
157
|
+
const src = source;
|
|
158
|
+
const result = { ...defaults };
|
|
159
|
+
for (const key of Object.keys(defaults)) {
|
|
160
|
+
const defaultValue = defaults[key];
|
|
161
|
+
const sourceValue = src[key];
|
|
162
|
+
if (sourceValue === undefined) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (defaultValue !== null &&
|
|
166
|
+
typeof defaultValue === 'object' &&
|
|
167
|
+
!Array.isArray(defaultValue) &&
|
|
168
|
+
sourceValue !== null &&
|
|
169
|
+
typeof sourceValue === 'object' &&
|
|
170
|
+
!Array.isArray(sourceValue)) {
|
|
171
|
+
result[key] = mergeWithDefault(sourceValue, defaultValue);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
result[key] = sourceValue;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Builder - Multi-turn Message Sequence
|
|
3
|
+
*/
|
|
4
|
+
import type { AIAnalysisInput } from '../types';
|
|
5
|
+
export interface MessageSequence {
|
|
6
|
+
systemPrompt: string;
|
|
7
|
+
messages: string[];
|
|
8
|
+
finalPrompt: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Build message sequence for multi-turn chat
|
|
12
|
+
*
|
|
13
|
+
* Sequence:
|
|
14
|
+
* 1. UserOverview
|
|
15
|
+
* 2. PeriodsSummary
|
|
16
|
+
* 3. Each PeriodContent/Chunk
|
|
17
|
+
* 4. Final prompt requesting analysis
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildMessageSequence(input: AIAnalysisInput): MessageSequence;
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Prompt Builder - Multi-turn Message Sequence
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.buildMessageSequence = buildMessageSequence;
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const path = __importStar(require("node:path"));
|
|
42
|
+
// Load system prompt from md file
|
|
43
|
+
const SYSTEM_PROMPT_PATH = path.join(__dirname, 'system-prompt.md');
|
|
44
|
+
function loadSystemPrompt() {
|
|
45
|
+
return fs.readFileSync(SYSTEM_PROMPT_PATH, 'utf-8');
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build message sequence for multi-turn chat
|
|
49
|
+
*
|
|
50
|
+
* Sequence:
|
|
51
|
+
* 1. UserOverview
|
|
52
|
+
* 2. PeriodsSummary
|
|
53
|
+
* 3. Each PeriodContent/Chunk
|
|
54
|
+
* 4. Final prompt requesting analysis
|
|
55
|
+
*/
|
|
56
|
+
function buildMessageSequence(input) {
|
|
57
|
+
const messages = [];
|
|
58
|
+
// 1. UserOverview
|
|
59
|
+
messages.push(JSON.stringify({ userOverview: input.userOverview }, null, 2));
|
|
60
|
+
// 2. PeriodsSummary
|
|
61
|
+
messages.push(JSON.stringify({ summary: input.summary }, null, 2));
|
|
62
|
+
// 3. Each content chunk
|
|
63
|
+
if (input.contents.length === 0) {
|
|
64
|
+
console.warn('Warning: contents is empty');
|
|
65
|
+
}
|
|
66
|
+
for (const content of input.contents) {
|
|
67
|
+
messages.push(JSON.stringify(content, null, 2));
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
systemPrompt: loadSystemPrompt(),
|
|
71
|
+
messages,
|
|
72
|
+
finalPrompt: '根据以上数据生成用户分析报告,严格按照 Output Schema 输出 JSON。',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=index.js.map
|