@content-reviewer/core 0.0.3 → 0.0.5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @content-reviewer/core
2
2
 
3
- Library for reviewing written content using LLMs.
3
+ An LLM-powered library for reviewing written content.
4
4
 
5
5
  ## Installation
6
6
 
@@ -11,8 +11,7 @@ npm install @content-reviewer/core
11
11
  ## Usage
12
12
 
13
13
  ```typescript
14
- import { ContentReviewer, createReviewConfig } from '@content-reviewer/core';
15
- import type { Document } from '@content-reviewer/core';
14
+ import { ContentReviewer, createReviewConfig, type Document } from '@content-reviewer/core';
16
15
 
17
16
  // 1. Configuration
18
17
  const config = createReviewConfig({
@@ -74,7 +73,7 @@ The outcome of a review.
74
73
  - `issues`: Array of `ReviewIssue` objects.
75
74
  - `summary`: AI-generated summary of the review.
76
75
 
77
- ## Custom Instruction
76
+ ## Custom Instructions
78
77
 
79
78
  Instructions (including persona and guidelines) can be provided as a string.
80
79
 
package/dist/index.d.mts CHANGED
@@ -23,11 +23,28 @@ declare const reviewResponseSchema: z.ZodObject<{
23
23
  lineNumber: z.ZodOptional<z.ZodNumber>;
24
24
  suggestion: z.ZodOptional<z.ZodString>;
25
25
  }, z.core.$strip>>;
26
- summary: z.ZodString;
27
26
  }, z.core.$strip>;
28
27
  type ReviewIssueSchema = z.infer<typeof reviewIssueSchema>;
29
28
  type ReviewResponseSchema = z.infer<typeof reviewResponseSchema>;
30
29
 
30
+ declare const SEVERITIES: {
31
+ readonly error: {
32
+ readonly priority: 3;
33
+ };
34
+ readonly warning: {
35
+ readonly priority: 2;
36
+ };
37
+ readonly suggestion: {
38
+ readonly priority: 1;
39
+ };
40
+ };
41
+ type SeverityKey = keyof typeof SEVERITIES;
42
+ type IssueSeverity = SeverityKey;
43
+ declare const SEVERITY_LEVELS: {
44
+ [K in IssueSeverity]: number;
45
+ };
46
+ declare const DEFAULT_SEVERITY_LEVEL: IssueSeverity;
47
+
31
48
  type Document = Readonly<{
32
49
  rawContent: string;
33
50
  source: string;
@@ -46,8 +63,8 @@ type ReviewConfig = Readonly<{
46
63
  instruction?: string;
47
64
  language: Language;
48
65
  llm: LLMConfig;
66
+ severityLevel?: IssueSeverity;
49
67
  }>;
50
- type IssueSeverity = 'error' | 'warning' | 'suggestion';
51
68
  type ReviewIssue = Readonly<{
52
69
  severity: IssueSeverity;
53
70
  message: string;
@@ -58,7 +75,6 @@ type ReviewIssue = Readonly<{
58
75
  type ReviewResult = Readonly<{
59
76
  source: string;
60
77
  issues: ReviewIssue[];
61
- summary: string;
62
78
  reviewedAt: Date;
63
79
  }>;
64
80
 
@@ -66,6 +82,7 @@ type ReviewConfigInput = Readonly<{
66
82
  instruction?: string;
67
83
  language?: Language;
68
84
  llm?: Partial<LLMConfig>;
85
+ severityLevel?: IssueSeverity;
69
86
  }>;
70
87
  declare const PROVIDER_DEFAULT_MODELS: Record<LLMProvider, string>;
71
88
  declare const DEFAULT_LLM_CONFIG: LLMConfig;
@@ -89,14 +106,13 @@ declare class ContentReviewer {
89
106
  constructor(config: ReviewConfig);
90
107
  review(document: Document): Promise<ReviewResult>;
91
108
  private runLLMReview;
92
- private generateSummary;
93
109
  private buildSystemPrompt;
94
110
  private buildUserPrompt;
95
111
  private findFirstMatchingLineNumber;
96
112
  }
97
113
 
98
- declare const DEFAULT_INSTRUCTION_EN = "You are a professional editor and proofreader.\nPlease review the provided text for basic writing issues according to the following criteria:\n\n# Review Criteria\n\n## Grammar & Spelling\n- Correct typos and spelling errors.\n- Fix grammatical mistakes.\n\n## Clarity & Flow\n- Ensure sentences are clear and easy to read.\n- Point out ambiguous or confusing phrasing.\n\n## Consistency\n- Check for contradictions within the text.\n- Ensure consistent terminology and formatting.\n";
99
- declare const DEFAULT_INSTRUCTION_JA = "\u3042\u306A\u305F\u306F\u30D7\u30ED\u306E\u7DE8\u96C6\u8005\u30FB\u6821\u6B63\u8005\u3067\u3059\u3002\n\u63D0\u4F9B\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\u3092\u3001\u4EE5\u4E0B\u306E\u57FA\u6E96\u306B\u5F93\u3063\u3066\u57FA\u672C\u7684\u306A\u6587\u7AE0\u306E\u554F\u984C\u70B9\u306B\u3064\u3044\u3066\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A\n\n# \u30EC\u30D3\u30E5\u30FC\u57FA\u6E96\n\n## \u8AA4\u5B57\u8131\u5B57\u30FB\u6587\u6CD5\n- \u8AA4\u5B57\u3084\u8131\u5B57\u3092\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n- \u6587\u6CD5\u7684\u306A\u8AA4\u308A\u3092\u4FEE\u6B63\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\n## \u308F\u304B\u308A\u3084\u3059\u3055\n- \u6587\u7AE0\u304C\u660E\u78BA\u3067\u8AAD\u307F\u3084\u3059\u3044\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n- \u66D6\u6627\u306A\u8868\u73FE\u3084\u5206\u304B\u308A\u306B\u304F\u3044\u8A00\u3044\u56DE\u3057\u304C\u3042\u308C\u3070\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\n## \u4E00\u8CAB\u6027\u30FB\u77DB\u76FE\n- \u6587\u4E2D\u3067\u306E\u77DB\u76FE\u70B9\u304C\u306A\u3044\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n- \u7528\u8A9E\u3084\u8868\u8A18\u306E\u63FA\u308C\uFF08\u4F8B\uFF1A\u300C\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u300D\u3068\u300C\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u30FC\u300D\u306E\u6DF7\u5728\u306A\u3069\uFF09\u3092\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n";
114
+ declare const DEFAULT_INSTRUCTION_EN = "You are a professional editor for technical writing.\nPlease review the provided text (e.g., blog posts, technical documents) and point out issues with clear, actionable suggestions.\n\n# Review Criteria\nReport each issue with the appropriate severity.\n\n## error\n- Typos / spelling mistakes\n- Grammar mistakes\n- Harassment, hate, or discrimination (personal attacks, slurs, dehumanizing language, advocating harm)\n- Exposure of sensitive information (API keys, secrets, personal data)\n- Dangerous instructions without proper warnings / safer alternatives\n- Technically incorrect or misleading statements\n\n## warning\n- Missing references/citations for non-obvious claims (when applicable)\n\n## suggestion\n- Missing assumptions / prerequisites (OS, versions, environment, context)\n- Reproducibility issues (missing steps, commands, expected outputs, pitfalls)\n- Missing scope clarification (what is covered / not covered)\n- Clarity improvements, wording refinements, optional re-structuring\n- Consistency improvements (terminology, formatting) when not misleading\n";
115
+ declare const DEFAULT_INSTRUCTION_JA = "\u3042\u306A\u305F\u306F\u6280\u8853\u6587\u66F8\u306B\u5F37\u3044\u30D7\u30ED\u306E\u7DE8\u96C6\u8005\u30FB\u6821\u6B63\u8005\u3067\u3059\u3002\n\u63D0\u4F9B\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\uFF08\u6280\u8853\u30D6\u30ED\u30B0\u8A18\u4E8B\u30FB\u6280\u8853\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u7B49\uFF09\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3001\u554F\u984C\u70B9\u3068\u6539\u5584\u6848\u3092\u5177\u4F53\u7684\u306B\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\n# \u30EC\u30D3\u30E5\u30FC\u57FA\u6E96\n\u5404issue\u306B\u306F\u9069\u5207\u306Aseverity\u3092\u4ED8\u3051\u3066\u5831\u544A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\n## error\n- \u8AA4\u5B57\u8131\u5B57\n- \u6587\u6CD5\u7684\u306A\u8AA4\u308A\n- \u4EBA\u6A29\u4FB5\u5BB3\u30FB\u5DEE\u5225\u30FB\u30D8\u30A4\u30C8\u30FB\u500B\u4EBA\u653B\u6483\uFF08\u4FAE\u8FB1/\u8511\u79F0/\u975E\u4EBA\u9593\u5316/\u66B4\u529B\u306E\u6247\u52D5\u306A\u3069\uFF09\n- API\u30AD\u30FC\u30FB\u79D8\u5BC6\u60C5\u5831\u30FB\u500B\u4EBA\u60C5\u5831\u306A\u3069\u306E\u9732\u51FA\n- \u5371\u967A\u306A\u624B\u9806\uFF08\u7834\u58CA\u7684\u64CD\u4F5C\u306A\u3069\uFF09\u306B\u6CE8\u610F\u66F8\u304D\u3084\u5B89\u5168\u7B56\u304C\u306A\u3044\n- \u6280\u8853\u7684\u306B\u8AA4\u3063\u3066\u3044\u308B\uFF0F\u8AA4\u89E3\u3092\u62DB\u304F\u4E3B\u5F35\n\n## warning\n- \u975E\u81EA\u660E\u306A\u4E3B\u5F35\u306B\u6839\u62E0\uFF08\u53C2\u7167\u30EA\u30F3\u30AF/\u4E00\u6B21\u60C5\u5831\u306A\u3069\uFF09\u304C\u4E0D\u8DB3\u3057\u3066\u3044\u308B\uFF08\u8A72\u5F53\u3059\u308B\u5834\u5408\uFF09\n\n## suggestion\n- \u524D\u63D0\u6761\u4EF6\uFF08OS/\u30D0\u30FC\u30B8\u30E7\u30F3/\u74B0\u5883/\u6761\u4EF6/\u5BFE\u8C61\u8AAD\u8005\u306A\u3069\uFF09\u306E\u4E0D\u8DB3\n- \u518D\u73FE\u6027\u306E\u4E0D\u8DB3\uFF08\u624B\u9806\u3001\u30B3\u30DE\u30F3\u30C9\u3001\u671F\u5F85\u7D50\u679C\u3001\u843D\u3068\u3057\u7A74\u3001\u629C\u3051\u6F0F\u308C\uFF09\n- \u30B9\u30B3\u30FC\u30D7\uFF08\u5BFE\u8C61/\u5BFE\u8C61\u5916\uFF09\u306E\u4E0D\u660E\u78BA\u3055\n- \u8868\u73FE\u306E\u5FAE\u8ABF\u6574\u3001\u308F\u304B\u308A\u3084\u3059\u3055\u30FB\u8AAD\u307F\u3084\u3059\u3055\u30FB\u6D41\u308C\u306E\u6539\u5584\u3001\u4EFB\u610F\u306E\u69CB\u6210\u6539\u5584\n- \u7528\u8A9E\u3084\u8868\u8A18\u306E\u63FA\u308C\u306A\u3069\u306E\u4E00\u8CAB\u6027\u6539\u5584\uFF08\u8AA4\u89E3\u3092\u62DB\u304B\u306A\u3044\u7BC4\u56F2\uFF09\n";
100
116
 
101
117
  declare class ContentReviewerError extends Error {
102
118
  constructor(message: string);
@@ -118,4 +134,6 @@ declare const ENV_VARS: {
118
134
  readonly GOOGLE_API_KEY: "GOOGLE_API_KEY";
119
135
  };
120
136
 
121
- export { AISdkClient, ContentReviewer, ContentReviewerError, DEFAULT_CONFIG, DEFAULT_INSTRUCTION_EN, DEFAULT_INSTRUCTION_JA, DEFAULT_LLM_CONFIG, type Document, ENV_VARS, type IssueSeverity, type LLMClient, type LLMConfig, LLMError, type LLMProvider, type Language, MissingApiKeyError, PROVIDER_DEFAULT_MODELS, type ReviewConfig, type ReviewConfigInput, type ReviewIssue, type ReviewIssueSchema, type ReviewResponseSchema, type ReviewResult, UnsupportedProviderError, createLLMClient, createReviewConfig, resolveApiKey, reviewIssueSchema, reviewResponseSchema, validateConfig };
137
+ declare function filterIssuesBySeverity(issues: readonly ReviewIssue[], minLevel: IssueSeverity): ReviewIssue[];
138
+
139
+ export { AISdkClient, ContentReviewer, ContentReviewerError, DEFAULT_CONFIG, DEFAULT_INSTRUCTION_EN, DEFAULT_INSTRUCTION_JA, DEFAULT_LLM_CONFIG, DEFAULT_SEVERITY_LEVEL, type Document, ENV_VARS, type IssueSeverity, type LLMClient, type LLMConfig, LLMError, type LLMProvider, type Language, MissingApiKeyError, PROVIDER_DEFAULT_MODELS, type ReviewConfig, type ReviewConfigInput, type ReviewIssue, type ReviewIssueSchema, type ReviewResponseSchema, type ReviewResult, SEVERITY_LEVELS, UnsupportedProviderError, createLLMClient, createReviewConfig, filterIssuesBySeverity, resolveApiKey, reviewIssueSchema, reviewResponseSchema, validateConfig };
package/dist/index.d.ts CHANGED
@@ -23,11 +23,28 @@ declare const reviewResponseSchema: z.ZodObject<{
23
23
  lineNumber: z.ZodOptional<z.ZodNumber>;
24
24
  suggestion: z.ZodOptional<z.ZodString>;
25
25
  }, z.core.$strip>>;
26
- summary: z.ZodString;
27
26
  }, z.core.$strip>;
28
27
  type ReviewIssueSchema = z.infer<typeof reviewIssueSchema>;
29
28
  type ReviewResponseSchema = z.infer<typeof reviewResponseSchema>;
30
29
 
30
+ declare const SEVERITIES: {
31
+ readonly error: {
32
+ readonly priority: 3;
33
+ };
34
+ readonly warning: {
35
+ readonly priority: 2;
36
+ };
37
+ readonly suggestion: {
38
+ readonly priority: 1;
39
+ };
40
+ };
41
+ type SeverityKey = keyof typeof SEVERITIES;
42
+ type IssueSeverity = SeverityKey;
43
+ declare const SEVERITY_LEVELS: {
44
+ [K in IssueSeverity]: number;
45
+ };
46
+ declare const DEFAULT_SEVERITY_LEVEL: IssueSeverity;
47
+
31
48
  type Document = Readonly<{
32
49
  rawContent: string;
33
50
  source: string;
@@ -46,8 +63,8 @@ type ReviewConfig = Readonly<{
46
63
  instruction?: string;
47
64
  language: Language;
48
65
  llm: LLMConfig;
66
+ severityLevel?: IssueSeverity;
49
67
  }>;
50
- type IssueSeverity = 'error' | 'warning' | 'suggestion';
51
68
  type ReviewIssue = Readonly<{
52
69
  severity: IssueSeverity;
53
70
  message: string;
@@ -58,7 +75,6 @@ type ReviewIssue = Readonly<{
58
75
  type ReviewResult = Readonly<{
59
76
  source: string;
60
77
  issues: ReviewIssue[];
61
- summary: string;
62
78
  reviewedAt: Date;
63
79
  }>;
64
80
 
@@ -66,6 +82,7 @@ type ReviewConfigInput = Readonly<{
66
82
  instruction?: string;
67
83
  language?: Language;
68
84
  llm?: Partial<LLMConfig>;
85
+ severityLevel?: IssueSeverity;
69
86
  }>;
70
87
  declare const PROVIDER_DEFAULT_MODELS: Record<LLMProvider, string>;
71
88
  declare const DEFAULT_LLM_CONFIG: LLMConfig;
@@ -89,14 +106,13 @@ declare class ContentReviewer {
89
106
  constructor(config: ReviewConfig);
90
107
  review(document: Document): Promise<ReviewResult>;
91
108
  private runLLMReview;
92
- private generateSummary;
93
109
  private buildSystemPrompt;
94
110
  private buildUserPrompt;
95
111
  private findFirstMatchingLineNumber;
96
112
  }
97
113
 
98
- declare const DEFAULT_INSTRUCTION_EN = "You are a professional editor and proofreader.\nPlease review the provided text for basic writing issues according to the following criteria:\n\n# Review Criteria\n\n## Grammar & Spelling\n- Correct typos and spelling errors.\n- Fix grammatical mistakes.\n\n## Clarity & Flow\n- Ensure sentences are clear and easy to read.\n- Point out ambiguous or confusing phrasing.\n\n## Consistency\n- Check for contradictions within the text.\n- Ensure consistent terminology and formatting.\n";
99
- declare const DEFAULT_INSTRUCTION_JA = "\u3042\u306A\u305F\u306F\u30D7\u30ED\u306E\u7DE8\u96C6\u8005\u30FB\u6821\u6B63\u8005\u3067\u3059\u3002\n\u63D0\u4F9B\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\u3092\u3001\u4EE5\u4E0B\u306E\u57FA\u6E96\u306B\u5F93\u3063\u3066\u57FA\u672C\u7684\u306A\u6587\u7AE0\u306E\u554F\u984C\u70B9\u306B\u3064\u3044\u3066\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A\n\n# \u30EC\u30D3\u30E5\u30FC\u57FA\u6E96\n\n## \u8AA4\u5B57\u8131\u5B57\u30FB\u6587\u6CD5\n- \u8AA4\u5B57\u3084\u8131\u5B57\u3092\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n- \u6587\u6CD5\u7684\u306A\u8AA4\u308A\u3092\u4FEE\u6B63\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\n## \u308F\u304B\u308A\u3084\u3059\u3055\n- \u6587\u7AE0\u304C\u660E\u78BA\u3067\u8AAD\u307F\u3084\u3059\u3044\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n- \u66D6\u6627\u306A\u8868\u73FE\u3084\u5206\u304B\u308A\u306B\u304F\u3044\u8A00\u3044\u56DE\u3057\u304C\u3042\u308C\u3070\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\n## \u4E00\u8CAB\u6027\u30FB\u77DB\u76FE\n- \u6587\u4E2D\u3067\u306E\u77DB\u76FE\u70B9\u304C\u306A\u3044\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n- \u7528\u8A9E\u3084\u8868\u8A18\u306E\u63FA\u308C\uFF08\u4F8B\uFF1A\u300C\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u300D\u3068\u300C\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u30FC\u300D\u306E\u6DF7\u5728\u306A\u3069\uFF09\u3092\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n";
114
+ declare const DEFAULT_INSTRUCTION_EN = "You are a professional editor for technical writing.\nPlease review the provided text (e.g., blog posts, technical documents) and point out issues with clear, actionable suggestions.\n\n# Review Criteria\nReport each issue with the appropriate severity.\n\n## error\n- Typos / spelling mistakes\n- Grammar mistakes\n- Harassment, hate, or discrimination (personal attacks, slurs, dehumanizing language, advocating harm)\n- Exposure of sensitive information (API keys, secrets, personal data)\n- Dangerous instructions without proper warnings / safer alternatives\n- Technically incorrect or misleading statements\n\n## warning\n- Missing references/citations for non-obvious claims (when applicable)\n\n## suggestion\n- Missing assumptions / prerequisites (OS, versions, environment, context)\n- Reproducibility issues (missing steps, commands, expected outputs, pitfalls)\n- Missing scope clarification (what is covered / not covered)\n- Clarity improvements, wording refinements, optional re-structuring\n- Consistency improvements (terminology, formatting) when not misleading\n";
115
+ declare const DEFAULT_INSTRUCTION_JA = "\u3042\u306A\u305F\u306F\u6280\u8853\u6587\u66F8\u306B\u5F37\u3044\u30D7\u30ED\u306E\u7DE8\u96C6\u8005\u30FB\u6821\u6B63\u8005\u3067\u3059\u3002\n\u63D0\u4F9B\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\uFF08\u6280\u8853\u30D6\u30ED\u30B0\u8A18\u4E8B\u30FB\u6280\u8853\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u7B49\uFF09\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3001\u554F\u984C\u70B9\u3068\u6539\u5584\u6848\u3092\u5177\u4F53\u7684\u306B\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\n# \u30EC\u30D3\u30E5\u30FC\u57FA\u6E96\n\u5404issue\u306B\u306F\u9069\u5207\u306Aseverity\u3092\u4ED8\u3051\u3066\u5831\u544A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\n## error\n- \u8AA4\u5B57\u8131\u5B57\n- \u6587\u6CD5\u7684\u306A\u8AA4\u308A\n- \u4EBA\u6A29\u4FB5\u5BB3\u30FB\u5DEE\u5225\u30FB\u30D8\u30A4\u30C8\u30FB\u500B\u4EBA\u653B\u6483\uFF08\u4FAE\u8FB1/\u8511\u79F0/\u975E\u4EBA\u9593\u5316/\u66B4\u529B\u306E\u6247\u52D5\u306A\u3069\uFF09\n- API\u30AD\u30FC\u30FB\u79D8\u5BC6\u60C5\u5831\u30FB\u500B\u4EBA\u60C5\u5831\u306A\u3069\u306E\u9732\u51FA\n- \u5371\u967A\u306A\u624B\u9806\uFF08\u7834\u58CA\u7684\u64CD\u4F5C\u306A\u3069\uFF09\u306B\u6CE8\u610F\u66F8\u304D\u3084\u5B89\u5168\u7B56\u304C\u306A\u3044\n- \u6280\u8853\u7684\u306B\u8AA4\u3063\u3066\u3044\u308B\uFF0F\u8AA4\u89E3\u3092\u62DB\u304F\u4E3B\u5F35\n\n## warning\n- \u975E\u81EA\u660E\u306A\u4E3B\u5F35\u306B\u6839\u62E0\uFF08\u53C2\u7167\u30EA\u30F3\u30AF/\u4E00\u6B21\u60C5\u5831\u306A\u3069\uFF09\u304C\u4E0D\u8DB3\u3057\u3066\u3044\u308B\uFF08\u8A72\u5F53\u3059\u308B\u5834\u5408\uFF09\n\n## suggestion\n- \u524D\u63D0\u6761\u4EF6\uFF08OS/\u30D0\u30FC\u30B8\u30E7\u30F3/\u74B0\u5883/\u6761\u4EF6/\u5BFE\u8C61\u8AAD\u8005\u306A\u3069\uFF09\u306E\u4E0D\u8DB3\n- \u518D\u73FE\u6027\u306E\u4E0D\u8DB3\uFF08\u624B\u9806\u3001\u30B3\u30DE\u30F3\u30C9\u3001\u671F\u5F85\u7D50\u679C\u3001\u843D\u3068\u3057\u7A74\u3001\u629C\u3051\u6F0F\u308C\uFF09\n- \u30B9\u30B3\u30FC\u30D7\uFF08\u5BFE\u8C61/\u5BFE\u8C61\u5916\uFF09\u306E\u4E0D\u660E\u78BA\u3055\n- \u8868\u73FE\u306E\u5FAE\u8ABF\u6574\u3001\u308F\u304B\u308A\u3084\u3059\u3055\u30FB\u8AAD\u307F\u3084\u3059\u3055\u30FB\u6D41\u308C\u306E\u6539\u5584\u3001\u4EFB\u610F\u306E\u69CB\u6210\u6539\u5584\n- \u7528\u8A9E\u3084\u8868\u8A18\u306E\u63FA\u308C\u306A\u3069\u306E\u4E00\u8CAB\u6027\u6539\u5584\uFF08\u8AA4\u89E3\u3092\u62DB\u304B\u306A\u3044\u7BC4\u56F2\uFF09\n";
100
116
 
101
117
  declare class ContentReviewerError extends Error {
102
118
  constructor(message: string);
@@ -118,4 +134,6 @@ declare const ENV_VARS: {
118
134
  readonly GOOGLE_API_KEY: "GOOGLE_API_KEY";
119
135
  };
120
136
 
121
- export { AISdkClient, ContentReviewer, ContentReviewerError, DEFAULT_CONFIG, DEFAULT_INSTRUCTION_EN, DEFAULT_INSTRUCTION_JA, DEFAULT_LLM_CONFIG, type Document, ENV_VARS, type IssueSeverity, type LLMClient, type LLMConfig, LLMError, type LLMProvider, type Language, MissingApiKeyError, PROVIDER_DEFAULT_MODELS, type ReviewConfig, type ReviewConfigInput, type ReviewIssue, type ReviewIssueSchema, type ReviewResponseSchema, type ReviewResult, UnsupportedProviderError, createLLMClient, createReviewConfig, resolveApiKey, reviewIssueSchema, reviewResponseSchema, validateConfig };
137
+ declare function filterIssuesBySeverity(issues: readonly ReviewIssue[], minLevel: IssueSeverity): ReviewIssue[];
138
+
139
+ export { AISdkClient, ContentReviewer, ContentReviewerError, DEFAULT_CONFIG, DEFAULT_INSTRUCTION_EN, DEFAULT_INSTRUCTION_JA, DEFAULT_LLM_CONFIG, DEFAULT_SEVERITY_LEVEL, type Document, ENV_VARS, type IssueSeverity, type LLMClient, type LLMConfig, LLMError, type LLMProvider, type Language, MissingApiKeyError, PROVIDER_DEFAULT_MODELS, type ReviewConfig, type ReviewConfigInput, type ReviewIssue, type ReviewIssueSchema, type ReviewResponseSchema, type ReviewResult, SEVERITY_LEVELS, UnsupportedProviderError, createLLMClient, createReviewConfig, filterIssuesBySeverity, resolveApiKey, reviewIssueSchema, reviewResponseSchema, validateConfig };
package/dist/index.js CHANGED
@@ -27,13 +27,16 @@ __export(index_exports, {
27
27
  DEFAULT_INSTRUCTION_EN: () => DEFAULT_INSTRUCTION_EN,
28
28
  DEFAULT_INSTRUCTION_JA: () => DEFAULT_INSTRUCTION_JA,
29
29
  DEFAULT_LLM_CONFIG: () => DEFAULT_LLM_CONFIG,
30
+ DEFAULT_SEVERITY_LEVEL: () => DEFAULT_SEVERITY_LEVEL,
30
31
  ENV_VARS: () => ENV_VARS,
31
32
  LLMError: () => LLMError,
32
33
  MissingApiKeyError: () => MissingApiKeyError,
33
34
  PROVIDER_DEFAULT_MODELS: () => PROVIDER_DEFAULT_MODELS,
35
+ SEVERITY_LEVELS: () => SEVERITY_LEVELS,
34
36
  UnsupportedProviderError: () => UnsupportedProviderError,
35
37
  createLLMClient: () => createLLMClient,
36
38
  createReviewConfig: () => createReviewConfig,
39
+ filterIssuesBySeverity: () => filterIssuesBySeverity,
37
40
  resolveApiKey: () => resolveApiKey,
38
41
  reviewIssueSchema: () => reviewIssueSchema,
39
42
  reviewResponseSchema: () => reviewResponseSchema,
@@ -43,16 +46,30 @@ module.exports = __toCommonJS(index_exports);
43
46
 
44
47
  // src/schemas.ts
45
48
  var import_zod = require("zod");
49
+
50
+ // src/severity.ts
51
+ var SEVERITIES = {
52
+ error: { priority: 3 },
53
+ warning: { priority: 2 },
54
+ suggestion: { priority: 1 }
55
+ };
56
+ var DEFAULT = "warning";
57
+ var SEVERITY_LEVELS = Object.fromEntries(
58
+ Object.entries(SEVERITIES).map(([k, v]) => [k, v.priority])
59
+ );
60
+ var DEFAULT_SEVERITY_LEVEL = DEFAULT;
61
+
62
+ // src/schemas.ts
63
+ var severityKeys = Object.keys(SEVERITY_LEVELS);
46
64
  var reviewIssueSchema = import_zod.z.object({
47
- severity: import_zod.z.enum(["error", "warning", "suggestion"]),
65
+ severity: import_zod.z.enum(severityKeys),
48
66
  message: import_zod.z.string(),
49
67
  matchText: import_zod.z.string().optional(),
50
68
  lineNumber: import_zod.z.number().optional(),
51
69
  suggestion: import_zod.z.string().optional()
52
70
  });
53
71
  var reviewResponseSchema = import_zod.z.object({
54
- issues: import_zod.z.array(reviewIssueSchema),
55
- summary: import_zod.z.string()
72
+ issues: import_zod.z.array(reviewIssueSchema)
56
73
  });
57
74
 
58
75
  // src/constants.ts
@@ -115,7 +132,8 @@ function createReviewConfig(input = {}) {
115
132
  provider,
116
133
  model,
117
134
  apiKey: input.llm?.apiKey
118
- }
135
+ },
136
+ severityLevel: input.severityLevel
119
137
  };
120
138
  }
121
139
  function resolveApiKey(config) {
@@ -150,6 +168,12 @@ function validateConfig(config) {
150
168
  if (!config.llm.model) {
151
169
  throw new Error("LLM model is required");
152
170
  }
171
+ if (config.severityLevel !== void 0 && !(config.severityLevel in SEVERITY_LEVELS)) {
172
+ const validLevels = Object.keys(SEVERITY_LEVELS).join(", ");
173
+ throw new Error(
174
+ `Invalid severity level: ${config.severityLevel}. Valid levels are: ${validLevels}`
175
+ );
176
+ }
153
177
  }
154
178
 
155
179
  // src/llm/ai-sdk-client.ts
@@ -215,47 +239,60 @@ function createLLMClient(config, apiKey) {
215
239
  }
216
240
 
217
241
  // src/default-instructions.ts
218
- var DEFAULT_INSTRUCTION_EN = `You are a professional editor and proofreader.
219
- Please review the provided text for basic writing issues according to the following criteria:
242
+ var DEFAULT_INSTRUCTION_EN = `You are a professional editor for technical writing.
243
+ Please review the provided text (e.g., blog posts, technical documents) and point out issues with clear, actionable suggestions.
220
244
 
221
245
  # Review Criteria
246
+ Report each issue with the appropriate severity.
222
247
 
223
- ## Grammar & Spelling
224
- - Correct typos and spelling errors.
225
- - Fix grammatical mistakes.
248
+ ## error
249
+ - Typos / spelling mistakes
250
+ - Grammar mistakes
251
+ - Harassment, hate, or discrimination (personal attacks, slurs, dehumanizing language, advocating harm)
252
+ - Exposure of sensitive information (API keys, secrets, personal data)
253
+ - Dangerous instructions without proper warnings / safer alternatives
254
+ - Technically incorrect or misleading statements
226
255
 
227
- ## Clarity & Flow
228
- - Ensure sentences are clear and easy to read.
229
- - Point out ambiguous or confusing phrasing.
256
+ ## warning
257
+ - Missing references/citations for non-obvious claims (when applicable)
230
258
 
231
- ## Consistency
232
- - Check for contradictions within the text.
233
- - Ensure consistent terminology and formatting.
259
+ ## suggestion
260
+ - Missing assumptions / prerequisites (OS, versions, environment, context)
261
+ - Reproducibility issues (missing steps, commands, expected outputs, pitfalls)
262
+ - Missing scope clarification (what is covered / not covered)
263
+ - Clarity improvements, wording refinements, optional re-structuring
264
+ - Consistency improvements (terminology, formatting) when not misleading
234
265
  `;
235
- var DEFAULT_INSTRUCTION_JA = `\u3042\u306A\u305F\u306F\u30D7\u30ED\u306E\u7DE8\u96C6\u8005\u30FB\u6821\u6B63\u8005\u3067\u3059\u3002
236
- \u63D0\u4F9B\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\u3092\u3001\u4EE5\u4E0B\u306E\u57FA\u6E96\u306B\u5F93\u3063\u3066\u57FA\u672C\u7684\u306A\u6587\u7AE0\u306E\u554F\u984C\u70B9\u306B\u3064\u3044\u3066\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A
266
+ var DEFAULT_INSTRUCTION_JA = `\u3042\u306A\u305F\u306F\u6280\u8853\u6587\u66F8\u306B\u5F37\u3044\u30D7\u30ED\u306E\u7DE8\u96C6\u8005\u30FB\u6821\u6B63\u8005\u3067\u3059\u3002
267
+ \u63D0\u4F9B\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\uFF08\u6280\u8853\u30D6\u30ED\u30B0\u8A18\u4E8B\u30FB\u6280\u8853\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u7B49\uFF09\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3001\u554F\u984C\u70B9\u3068\u6539\u5584\u6848\u3092\u5177\u4F53\u7684\u306B\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002
237
268
 
238
269
  # \u30EC\u30D3\u30E5\u30FC\u57FA\u6E96
270
+ \u5404issue\u306B\u306F\u9069\u5207\u306Aseverity\u3092\u4ED8\u3051\u3066\u5831\u544A\u3057\u3066\u304F\u3060\u3055\u3044\u3002
239
271
 
240
- ## \u8AA4\u5B57\u8131\u5B57\u30FB\u6587\u6CD5
241
- - \u8AA4\u5B57\u3084\u8131\u5B57\u3092\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002
242
- - \u6587\u6CD5\u7684\u306A\u8AA4\u308A\u3092\u4FEE\u6B63\u3057\u3066\u304F\u3060\u3055\u3044\u3002
272
+ ## error
273
+ - \u8AA4\u5B57\u8131\u5B57
274
+ - \u6587\u6CD5\u7684\u306A\u8AA4\u308A
275
+ - \u4EBA\u6A29\u4FB5\u5BB3\u30FB\u5DEE\u5225\u30FB\u30D8\u30A4\u30C8\u30FB\u500B\u4EBA\u653B\u6483\uFF08\u4FAE\u8FB1/\u8511\u79F0/\u975E\u4EBA\u9593\u5316/\u66B4\u529B\u306E\u6247\u52D5\u306A\u3069\uFF09
276
+ - API\u30AD\u30FC\u30FB\u79D8\u5BC6\u60C5\u5831\u30FB\u500B\u4EBA\u60C5\u5831\u306A\u3069\u306E\u9732\u51FA
277
+ - \u5371\u967A\u306A\u624B\u9806\uFF08\u7834\u58CA\u7684\u64CD\u4F5C\u306A\u3069\uFF09\u306B\u6CE8\u610F\u66F8\u304D\u3084\u5B89\u5168\u7B56\u304C\u306A\u3044
278
+ - \u6280\u8853\u7684\u306B\u8AA4\u3063\u3066\u3044\u308B\uFF0F\u8AA4\u89E3\u3092\u62DB\u304F\u4E3B\u5F35
243
279
 
244
- ## \u308F\u304B\u308A\u3084\u3059\u3055
245
- - \u6587\u7AE0\u304C\u660E\u78BA\u3067\u8AAD\u307F\u3084\u3059\u3044\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
246
- - \u66D6\u6627\u306A\u8868\u73FE\u3084\u5206\u304B\u308A\u306B\u304F\u3044\u8A00\u3044\u56DE\u3057\u304C\u3042\u308C\u3070\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002
280
+ ## warning
281
+ - \u975E\u81EA\u660E\u306A\u4E3B\u5F35\u306B\u6839\u62E0\uFF08\u53C2\u7167\u30EA\u30F3\u30AF/\u4E00\u6B21\u60C5\u5831\u306A\u3069\uFF09\u304C\u4E0D\u8DB3\u3057\u3066\u3044\u308B\uFF08\u8A72\u5F53\u3059\u308B\u5834\u5408\uFF09
247
282
 
248
- ## \u4E00\u8CAB\u6027\u30FB\u77DB\u76FE
249
- - \u6587\u4E2D\u3067\u306E\u77DB\u76FE\u70B9\u304C\u306A\u3044\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
250
- - \u7528\u8A9E\u3084\u8868\u8A18\u306E\u63FA\u308C\uFF08\u4F8B\uFF1A\u300C\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u300D\u3068\u300C\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u30FC\u300D\u306E\u6DF7\u5728\u306A\u3069\uFF09\u3092\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002
283
+ ## suggestion
284
+ - \u524D\u63D0\u6761\u4EF6\uFF08OS/\u30D0\u30FC\u30B8\u30E7\u30F3/\u74B0\u5883/\u6761\u4EF6/\u5BFE\u8C61\u8AAD\u8005\u306A\u3069\uFF09\u306E\u4E0D\u8DB3
285
+ - \u518D\u73FE\u6027\u306E\u4E0D\u8DB3\uFF08\u624B\u9806\u3001\u30B3\u30DE\u30F3\u30C9\u3001\u671F\u5F85\u7D50\u679C\u3001\u843D\u3068\u3057\u7A74\u3001\u629C\u3051\u6F0F\u308C\uFF09
286
+ - \u30B9\u30B3\u30FC\u30D7\uFF08\u5BFE\u8C61/\u5BFE\u8C61\u5916\uFF09\u306E\u4E0D\u660E\u78BA\u3055
287
+ - \u8868\u73FE\u306E\u5FAE\u8ABF\u6574\u3001\u308F\u304B\u308A\u3084\u3059\u3055\u30FB\u8AAD\u307F\u3084\u3059\u3055\u30FB\u6D41\u308C\u306E\u6539\u5584\u3001\u4EFB\u610F\u306E\u69CB\u6210\u6539\u5584
288
+ - \u7528\u8A9E\u3084\u8868\u8A18\u306E\u63FA\u308C\u306A\u3069\u306E\u4E00\u8CAB\u6027\u6539\u5584\uFF08\u8AA4\u89E3\u3092\u62DB\u304B\u306A\u3044\u7BC4\u56F2\uFF09
251
289
  `;
252
290
 
253
291
  // src/prompts.ts
254
292
  var allPrompts = {
255
293
  ja: {
256
- generateSummary: (errorCount, warningCount) => `\u30EC\u30D3\u30E5\u30FC\u5B8C\u4E86\u3002\u30A8\u30E9\u30FC${errorCount}\u4EF6\u3001\u8B66\u544A${warningCount}\u4EF6\u3092\u691C\u51FA\u3002`,
257
294
  buildSystemPrompt: ({ instruction }) => {
258
- const instructions = instruction || DEFAULT_INSTRUCTION_JA;
295
+ const instructions = (instruction || DEFAULT_INSTRUCTION_JA).trimEnd() + "\n";
259
296
  return `${instructions}
260
297
  \u30EC\u30D3\u30E5\u30FC\u7D50\u679C\u306F\u65E5\u672C\u8A9E\u3067\u3001\u4EE5\u4E0B\u306EJSON\u69CB\u9020\u3067\u8FD4\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A
261
298
  - issues: \u898B\u3064\u304B\u3063\u305F\u554F\u984C\u70B9\u306E\u914D\u5217
@@ -266,19 +303,18 @@ var allPrompts = {
266
303
  - message: \u554F\u984C\u306E\u8AAC\u660E
267
304
  - matchText: \u554F\u984C\u7B87\u6240\u3092\u542B\u3080\u30C6\u30AD\u30B9\u30C8\u7247\uFF0810-50\u6587\u5B57\u7A0B\u5EA6\u3002\u5B8C\u5168\u4E00\u81F4\u3067\u304D\u308B\u56FA\u6709\u306E\u30C6\u30AD\u30B9\u30C8\u3092\u629C\u304D\u51FA\u3057\u3066\u304F\u3060\u3055\u3044\uFF09
268
305
  - suggestion: \u6539\u5584\u63D0\u6848\uFF08\u30AA\u30D7\u30B7\u30E7\u30F3\uFF09
269
- - summary: \u5168\u4F53\u7684\u306A\u7DCF\u8A55\uFF082-3\u6587\u7A0B\u5EA6\uFF09
270
306
 
271
307
  \u6CE8\u610F\uFF1A
308
+ - \u6709\u52B9\u306AJSON\u306E\u307F\u3092\u8FD4\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u524D\u5F8C\u306B\u6587\u7AE0\u3084Markdown\u306E\u30B3\u30FC\u30C9\u30D6\u30ED\u30C3\u30AF\u7B49\u3092\u4ED8\u3051\u306A\u3044\u3067\u304F\u3060\u3055\u3044\uFF09\u3002
272
309
  - lineNumber\u306F\u4E0D\u8981\u3067\u3059\u3002matchText\u306E\u307F\u3092\u63D0\u4F9B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
273
310
  - \u5EFA\u8A2D\u7684\u3067\u5177\u4F53\u7684\u306A\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u63D0\u4F9B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
274
311
  `;
275
312
  },
276
- buildUserPrompt: () => "\u4EE5\u4E0B\u306E\u8A18\u4E8B\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A\n\n---\n"
313
+ buildUserPrompt: () => "\u4EE5\u4E0B\u306E\u30C6\u30AD\u30B9\u30C8\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A\n\n\n"
277
314
  },
278
315
  en: {
279
- generateSummary: (errorCount, warningCount) => `Review completed. Found ${errorCount} errors and ${warningCount} warnings.`,
280
316
  buildSystemPrompt: ({ instruction }) => {
281
- const instructions = instruction || DEFAULT_INSTRUCTION_EN;
317
+ const instructions = (instruction || DEFAULT_INSTRUCTION_EN).trimEnd() + "\n";
282
318
  return `${instructions}
283
319
  Provide the review results in English with the following JSON structure:
284
320
  - issues: Array of found issues
@@ -289,14 +325,14 @@ Provide the review results in English with the following JSON structure:
289
325
  - message: Issue description
290
326
  - matchText: Text snippet containing the issue (10-50 characters, extract unique text that can be exactly matched)
291
327
  - suggestion: Improvement suggestion (optional)
292
- - summary: Overall assessment (2-3 sentences)
293
328
 
294
329
  Note:
330
+ - Return valid JSON only (do not wrap in markdown code fences or add extra text).
295
331
  - Do not provide lineNumber. Only provide matchText.
296
332
  - Provide constructive and specific feedback.
297
333
  `;
298
334
  },
299
- buildUserPrompt: () => "Please review the following article:\n\n---\n"
335
+ buildUserPrompt: () => "Please review the following text:\n\n\n"
300
336
  }
301
337
  };
302
338
  function getLanguagePrompts(language) {
@@ -306,6 +342,12 @@ function getLanguagePrompts(language) {
306
342
  throw new Error(`Unhandled language: ${language}`);
307
343
  }
308
344
 
345
+ // src/filter.ts
346
+ function filterIssuesBySeverity(issues, minLevel) {
347
+ const minLevelValue = SEVERITY_LEVELS[minLevel];
348
+ return issues.filter((issue) => SEVERITY_LEVELS[issue.severity] >= minLevelValue);
349
+ }
350
+
309
351
  // src/reviewer.ts
310
352
  var ContentReviewer = class {
311
353
  constructor(config) {
@@ -313,11 +355,10 @@ var ContentReviewer = class {
313
355
  }
314
356
  async review(document) {
315
357
  const llmResult = await this.runLLMReview(document);
316
- const summary = llmResult.summary || this.generateSummary(llmResult.issues);
358
+ const issues = this.config.severityLevel ? filterIssuesBySeverity(llmResult.issues, this.config.severityLevel) : llmResult.issues;
317
359
  return {
318
360
  source: document.source,
319
- issues: llmResult.issues,
320
- summary,
361
+ issues,
321
362
  reviewedAt: /* @__PURE__ */ new Date()
322
363
  };
323
364
  }
@@ -331,16 +372,7 @@ var ContentReviewer = class {
331
372
  ...issue,
332
373
  lineNumber: issue.matchText ? this.findFirstMatchingLineNumber(document.rawContent, issue.matchText) : void 0
333
374
  }));
334
- return {
335
- issues,
336
- summary: reviewData.summary
337
- };
338
- }
339
- generateSummary(issues) {
340
- const errorCount = issues.filter((i) => i.severity === "error").length;
341
- const warningCount = issues.filter((i) => i.severity === "warning").length;
342
- const { generateSummary } = getLanguagePrompts(this.config.language);
343
- return generateSummary(errorCount, warningCount);
375
+ return { issues };
344
376
  }
345
377
  buildSystemPrompt() {
346
378
  const { instruction, language } = this.config;
@@ -351,7 +383,7 @@ var ContentReviewer = class {
351
383
  const { language } = this.config;
352
384
  const { buildUserPrompt } = getLanguagePrompts(language);
353
385
  const prompt = buildUserPrompt();
354
- return prompt + document.rawContent + "\n---";
386
+ return prompt + document.rawContent;
355
387
  }
356
388
  findFirstMatchingLineNumber(rawContent, matchText) {
357
389
  const index = rawContent.indexOf(matchText);
@@ -379,13 +411,16 @@ var ContentReviewer = class {
379
411
  DEFAULT_INSTRUCTION_EN,
380
412
  DEFAULT_INSTRUCTION_JA,
381
413
  DEFAULT_LLM_CONFIG,
414
+ DEFAULT_SEVERITY_LEVEL,
382
415
  ENV_VARS,
383
416
  LLMError,
384
417
  MissingApiKeyError,
385
418
  PROVIDER_DEFAULT_MODELS,
419
+ SEVERITY_LEVELS,
386
420
  UnsupportedProviderError,
387
421
  createLLMClient,
388
422
  createReviewConfig,
423
+ filterIssuesBySeverity,
389
424
  resolveApiKey,
390
425
  reviewIssueSchema,
391
426
  reviewResponseSchema,
package/dist/index.mjs CHANGED
@@ -1,15 +1,29 @@
1
1
  // src/schemas.ts
2
2
  import { z } from "zod";
3
+
4
+ // src/severity.ts
5
+ var SEVERITIES = {
6
+ error: { priority: 3 },
7
+ warning: { priority: 2 },
8
+ suggestion: { priority: 1 }
9
+ };
10
+ var DEFAULT = "warning";
11
+ var SEVERITY_LEVELS = Object.fromEntries(
12
+ Object.entries(SEVERITIES).map(([k, v]) => [k, v.priority])
13
+ );
14
+ var DEFAULT_SEVERITY_LEVEL = DEFAULT;
15
+
16
+ // src/schemas.ts
17
+ var severityKeys = Object.keys(SEVERITY_LEVELS);
3
18
  var reviewIssueSchema = z.object({
4
- severity: z.enum(["error", "warning", "suggestion"]),
19
+ severity: z.enum(severityKeys),
5
20
  message: z.string(),
6
21
  matchText: z.string().optional(),
7
22
  lineNumber: z.number().optional(),
8
23
  suggestion: z.string().optional()
9
24
  });
10
25
  var reviewResponseSchema = z.object({
11
- issues: z.array(reviewIssueSchema),
12
- summary: z.string()
26
+ issues: z.array(reviewIssueSchema)
13
27
  });
14
28
 
15
29
  // src/constants.ts
@@ -72,7 +86,8 @@ function createReviewConfig(input = {}) {
72
86
  provider,
73
87
  model,
74
88
  apiKey: input.llm?.apiKey
75
- }
89
+ },
90
+ severityLevel: input.severityLevel
76
91
  };
77
92
  }
78
93
  function resolveApiKey(config) {
@@ -107,6 +122,12 @@ function validateConfig(config) {
107
122
  if (!config.llm.model) {
108
123
  throw new Error("LLM model is required");
109
124
  }
125
+ if (config.severityLevel !== void 0 && !(config.severityLevel in SEVERITY_LEVELS)) {
126
+ const validLevels = Object.keys(SEVERITY_LEVELS).join(", ");
127
+ throw new Error(
128
+ `Invalid severity level: ${config.severityLevel}. Valid levels are: ${validLevels}`
129
+ );
130
+ }
110
131
  }
111
132
 
112
133
  // src/llm/ai-sdk-client.ts
@@ -172,47 +193,60 @@ function createLLMClient(config, apiKey) {
172
193
  }
173
194
 
174
195
  // src/default-instructions.ts
175
- var DEFAULT_INSTRUCTION_EN = `You are a professional editor and proofreader.
176
- Please review the provided text for basic writing issues according to the following criteria:
196
+ var DEFAULT_INSTRUCTION_EN = `You are a professional editor for technical writing.
197
+ Please review the provided text (e.g., blog posts, technical documents) and point out issues with clear, actionable suggestions.
177
198
 
178
199
  # Review Criteria
200
+ Report each issue with the appropriate severity.
179
201
 
180
- ## Grammar & Spelling
181
- - Correct typos and spelling errors.
182
- - Fix grammatical mistakes.
202
+ ## error
203
+ - Typos / spelling mistakes
204
+ - Grammar mistakes
205
+ - Harassment, hate, or discrimination (personal attacks, slurs, dehumanizing language, advocating harm)
206
+ - Exposure of sensitive information (API keys, secrets, personal data)
207
+ - Dangerous instructions without proper warnings / safer alternatives
208
+ - Technically incorrect or misleading statements
183
209
 
184
- ## Clarity & Flow
185
- - Ensure sentences are clear and easy to read.
186
- - Point out ambiguous or confusing phrasing.
210
+ ## warning
211
+ - Missing references/citations for non-obvious claims (when applicable)
187
212
 
188
- ## Consistency
189
- - Check for contradictions within the text.
190
- - Ensure consistent terminology and formatting.
213
+ ## suggestion
214
+ - Missing assumptions / prerequisites (OS, versions, environment, context)
215
+ - Reproducibility issues (missing steps, commands, expected outputs, pitfalls)
216
+ - Missing scope clarification (what is covered / not covered)
217
+ - Clarity improvements, wording refinements, optional re-structuring
218
+ - Consistency improvements (terminology, formatting) when not misleading
191
219
  `;
192
- var DEFAULT_INSTRUCTION_JA = `\u3042\u306A\u305F\u306F\u30D7\u30ED\u306E\u7DE8\u96C6\u8005\u30FB\u6821\u6B63\u8005\u3067\u3059\u3002
193
- \u63D0\u4F9B\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\u3092\u3001\u4EE5\u4E0B\u306E\u57FA\u6E96\u306B\u5F93\u3063\u3066\u57FA\u672C\u7684\u306A\u6587\u7AE0\u306E\u554F\u984C\u70B9\u306B\u3064\u3044\u3066\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A
220
+ var DEFAULT_INSTRUCTION_JA = `\u3042\u306A\u305F\u306F\u6280\u8853\u6587\u66F8\u306B\u5F37\u3044\u30D7\u30ED\u306E\u7DE8\u96C6\u8005\u30FB\u6821\u6B63\u8005\u3067\u3059\u3002
221
+ \u63D0\u4F9B\u3055\u308C\u305F\u30C6\u30AD\u30B9\u30C8\uFF08\u6280\u8853\u30D6\u30ED\u30B0\u8A18\u4E8B\u30FB\u6280\u8853\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u7B49\uFF09\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3001\u554F\u984C\u70B9\u3068\u6539\u5584\u6848\u3092\u5177\u4F53\u7684\u306B\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002
194
222
 
195
223
  # \u30EC\u30D3\u30E5\u30FC\u57FA\u6E96
224
+ \u5404issue\u306B\u306F\u9069\u5207\u306Aseverity\u3092\u4ED8\u3051\u3066\u5831\u544A\u3057\u3066\u304F\u3060\u3055\u3044\u3002
196
225
 
197
- ## \u8AA4\u5B57\u8131\u5B57\u30FB\u6587\u6CD5
198
- - \u8AA4\u5B57\u3084\u8131\u5B57\u3092\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002
199
- - \u6587\u6CD5\u7684\u306A\u8AA4\u308A\u3092\u4FEE\u6B63\u3057\u3066\u304F\u3060\u3055\u3044\u3002
226
+ ## error
227
+ - \u8AA4\u5B57\u8131\u5B57
228
+ - \u6587\u6CD5\u7684\u306A\u8AA4\u308A
229
+ - \u4EBA\u6A29\u4FB5\u5BB3\u30FB\u5DEE\u5225\u30FB\u30D8\u30A4\u30C8\u30FB\u500B\u4EBA\u653B\u6483\uFF08\u4FAE\u8FB1/\u8511\u79F0/\u975E\u4EBA\u9593\u5316/\u66B4\u529B\u306E\u6247\u52D5\u306A\u3069\uFF09
230
+ - API\u30AD\u30FC\u30FB\u79D8\u5BC6\u60C5\u5831\u30FB\u500B\u4EBA\u60C5\u5831\u306A\u3069\u306E\u9732\u51FA
231
+ - \u5371\u967A\u306A\u624B\u9806\uFF08\u7834\u58CA\u7684\u64CD\u4F5C\u306A\u3069\uFF09\u306B\u6CE8\u610F\u66F8\u304D\u3084\u5B89\u5168\u7B56\u304C\u306A\u3044
232
+ - \u6280\u8853\u7684\u306B\u8AA4\u3063\u3066\u3044\u308B\uFF0F\u8AA4\u89E3\u3092\u62DB\u304F\u4E3B\u5F35
200
233
 
201
- ## \u308F\u304B\u308A\u3084\u3059\u3055
202
- - \u6587\u7AE0\u304C\u660E\u78BA\u3067\u8AAD\u307F\u3084\u3059\u3044\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
203
- - \u66D6\u6627\u306A\u8868\u73FE\u3084\u5206\u304B\u308A\u306B\u304F\u3044\u8A00\u3044\u56DE\u3057\u304C\u3042\u308C\u3070\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002
234
+ ## warning
235
+ - \u975E\u81EA\u660E\u306A\u4E3B\u5F35\u306B\u6839\u62E0\uFF08\u53C2\u7167\u30EA\u30F3\u30AF/\u4E00\u6B21\u60C5\u5831\u306A\u3069\uFF09\u304C\u4E0D\u8DB3\u3057\u3066\u3044\u308B\uFF08\u8A72\u5F53\u3059\u308B\u5834\u5408\uFF09
204
236
 
205
- ## \u4E00\u8CAB\u6027\u30FB\u77DB\u76FE
206
- - \u6587\u4E2D\u3067\u306E\u77DB\u76FE\u70B9\u304C\u306A\u3044\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002
207
- - \u7528\u8A9E\u3084\u8868\u8A18\u306E\u63FA\u308C\uFF08\u4F8B\uFF1A\u300C\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u300D\u3068\u300C\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u30FC\u300D\u306E\u6DF7\u5728\u306A\u3069\uFF09\u3092\u6307\u6458\u3057\u3066\u304F\u3060\u3055\u3044\u3002
237
+ ## suggestion
238
+ - \u524D\u63D0\u6761\u4EF6\uFF08OS/\u30D0\u30FC\u30B8\u30E7\u30F3/\u74B0\u5883/\u6761\u4EF6/\u5BFE\u8C61\u8AAD\u8005\u306A\u3069\uFF09\u306E\u4E0D\u8DB3
239
+ - \u518D\u73FE\u6027\u306E\u4E0D\u8DB3\uFF08\u624B\u9806\u3001\u30B3\u30DE\u30F3\u30C9\u3001\u671F\u5F85\u7D50\u679C\u3001\u843D\u3068\u3057\u7A74\u3001\u629C\u3051\u6F0F\u308C\uFF09
240
+ - \u30B9\u30B3\u30FC\u30D7\uFF08\u5BFE\u8C61/\u5BFE\u8C61\u5916\uFF09\u306E\u4E0D\u660E\u78BA\u3055
241
+ - \u8868\u73FE\u306E\u5FAE\u8ABF\u6574\u3001\u308F\u304B\u308A\u3084\u3059\u3055\u30FB\u8AAD\u307F\u3084\u3059\u3055\u30FB\u6D41\u308C\u306E\u6539\u5584\u3001\u4EFB\u610F\u306E\u69CB\u6210\u6539\u5584
242
+ - \u7528\u8A9E\u3084\u8868\u8A18\u306E\u63FA\u308C\u306A\u3069\u306E\u4E00\u8CAB\u6027\u6539\u5584\uFF08\u8AA4\u89E3\u3092\u62DB\u304B\u306A\u3044\u7BC4\u56F2\uFF09
208
243
  `;
209
244
 
210
245
  // src/prompts.ts
211
246
  var allPrompts = {
212
247
  ja: {
213
- generateSummary: (errorCount, warningCount) => `\u30EC\u30D3\u30E5\u30FC\u5B8C\u4E86\u3002\u30A8\u30E9\u30FC${errorCount}\u4EF6\u3001\u8B66\u544A${warningCount}\u4EF6\u3092\u691C\u51FA\u3002`,
214
248
  buildSystemPrompt: ({ instruction }) => {
215
- const instructions = instruction || DEFAULT_INSTRUCTION_JA;
249
+ const instructions = (instruction || DEFAULT_INSTRUCTION_JA).trimEnd() + "\n";
216
250
  return `${instructions}
217
251
  \u30EC\u30D3\u30E5\u30FC\u7D50\u679C\u306F\u65E5\u672C\u8A9E\u3067\u3001\u4EE5\u4E0B\u306EJSON\u69CB\u9020\u3067\u8FD4\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A
218
252
  - issues: \u898B\u3064\u304B\u3063\u305F\u554F\u984C\u70B9\u306E\u914D\u5217
@@ -223,19 +257,18 @@ var allPrompts = {
223
257
  - message: \u554F\u984C\u306E\u8AAC\u660E
224
258
  - matchText: \u554F\u984C\u7B87\u6240\u3092\u542B\u3080\u30C6\u30AD\u30B9\u30C8\u7247\uFF0810-50\u6587\u5B57\u7A0B\u5EA6\u3002\u5B8C\u5168\u4E00\u81F4\u3067\u304D\u308B\u56FA\u6709\u306E\u30C6\u30AD\u30B9\u30C8\u3092\u629C\u304D\u51FA\u3057\u3066\u304F\u3060\u3055\u3044\uFF09
225
259
  - suggestion: \u6539\u5584\u63D0\u6848\uFF08\u30AA\u30D7\u30B7\u30E7\u30F3\uFF09
226
- - summary: \u5168\u4F53\u7684\u306A\u7DCF\u8A55\uFF082-3\u6587\u7A0B\u5EA6\uFF09
227
260
 
228
261
  \u6CE8\u610F\uFF1A
262
+ - \u6709\u52B9\u306AJSON\u306E\u307F\u3092\u8FD4\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u524D\u5F8C\u306B\u6587\u7AE0\u3084Markdown\u306E\u30B3\u30FC\u30C9\u30D6\u30ED\u30C3\u30AF\u7B49\u3092\u4ED8\u3051\u306A\u3044\u3067\u304F\u3060\u3055\u3044\uFF09\u3002
229
263
  - lineNumber\u306F\u4E0D\u8981\u3067\u3059\u3002matchText\u306E\u307F\u3092\u63D0\u4F9B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
230
264
  - \u5EFA\u8A2D\u7684\u3067\u5177\u4F53\u7684\u306A\u30D5\u30A3\u30FC\u30C9\u30D0\u30C3\u30AF\u3092\u63D0\u4F9B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
231
265
  `;
232
266
  },
233
- buildUserPrompt: () => "\u4EE5\u4E0B\u306E\u8A18\u4E8B\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A\n\n---\n"
267
+ buildUserPrompt: () => "\u4EE5\u4E0B\u306E\u30C6\u30AD\u30B9\u30C8\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A\n\n\n"
234
268
  },
235
269
  en: {
236
- generateSummary: (errorCount, warningCount) => `Review completed. Found ${errorCount} errors and ${warningCount} warnings.`,
237
270
  buildSystemPrompt: ({ instruction }) => {
238
- const instructions = instruction || DEFAULT_INSTRUCTION_EN;
271
+ const instructions = (instruction || DEFAULT_INSTRUCTION_EN).trimEnd() + "\n";
239
272
  return `${instructions}
240
273
  Provide the review results in English with the following JSON structure:
241
274
  - issues: Array of found issues
@@ -246,14 +279,14 @@ Provide the review results in English with the following JSON structure:
246
279
  - message: Issue description
247
280
  - matchText: Text snippet containing the issue (10-50 characters, extract unique text that can be exactly matched)
248
281
  - suggestion: Improvement suggestion (optional)
249
- - summary: Overall assessment (2-3 sentences)
250
282
 
251
283
  Note:
284
+ - Return valid JSON only (do not wrap in markdown code fences or add extra text).
252
285
  - Do not provide lineNumber. Only provide matchText.
253
286
  - Provide constructive and specific feedback.
254
287
  `;
255
288
  },
256
- buildUserPrompt: () => "Please review the following article:\n\n---\n"
289
+ buildUserPrompt: () => "Please review the following text:\n\n\n"
257
290
  }
258
291
  };
259
292
  function getLanguagePrompts(language) {
@@ -263,6 +296,12 @@ function getLanguagePrompts(language) {
263
296
  throw new Error(`Unhandled language: ${language}`);
264
297
  }
265
298
 
299
+ // src/filter.ts
300
+ function filterIssuesBySeverity(issues, minLevel) {
301
+ const minLevelValue = SEVERITY_LEVELS[minLevel];
302
+ return issues.filter((issue) => SEVERITY_LEVELS[issue.severity] >= minLevelValue);
303
+ }
304
+
266
305
  // src/reviewer.ts
267
306
  var ContentReviewer = class {
268
307
  constructor(config) {
@@ -270,11 +309,10 @@ var ContentReviewer = class {
270
309
  }
271
310
  async review(document) {
272
311
  const llmResult = await this.runLLMReview(document);
273
- const summary = llmResult.summary || this.generateSummary(llmResult.issues);
312
+ const issues = this.config.severityLevel ? filterIssuesBySeverity(llmResult.issues, this.config.severityLevel) : llmResult.issues;
274
313
  return {
275
314
  source: document.source,
276
- issues: llmResult.issues,
277
- summary,
315
+ issues,
278
316
  reviewedAt: /* @__PURE__ */ new Date()
279
317
  };
280
318
  }
@@ -288,16 +326,7 @@ var ContentReviewer = class {
288
326
  ...issue,
289
327
  lineNumber: issue.matchText ? this.findFirstMatchingLineNumber(document.rawContent, issue.matchText) : void 0
290
328
  }));
291
- return {
292
- issues,
293
- summary: reviewData.summary
294
- };
295
- }
296
- generateSummary(issues) {
297
- const errorCount = issues.filter((i) => i.severity === "error").length;
298
- const warningCount = issues.filter((i) => i.severity === "warning").length;
299
- const { generateSummary } = getLanguagePrompts(this.config.language);
300
- return generateSummary(errorCount, warningCount);
329
+ return { issues };
301
330
  }
302
331
  buildSystemPrompt() {
303
332
  const { instruction, language } = this.config;
@@ -308,7 +337,7 @@ var ContentReviewer = class {
308
337
  const { language } = this.config;
309
338
  const { buildUserPrompt } = getLanguagePrompts(language);
310
339
  const prompt = buildUserPrompt();
311
- return prompt + document.rawContent + "\n---";
340
+ return prompt + document.rawContent;
312
341
  }
313
342
  findFirstMatchingLineNumber(rawContent, matchText) {
314
343
  const index = rawContent.indexOf(matchText);
@@ -335,13 +364,16 @@ export {
335
364
  DEFAULT_INSTRUCTION_EN,
336
365
  DEFAULT_INSTRUCTION_JA,
337
366
  DEFAULT_LLM_CONFIG,
367
+ DEFAULT_SEVERITY_LEVEL,
338
368
  ENV_VARS,
339
369
  LLMError,
340
370
  MissingApiKeyError,
341
371
  PROVIDER_DEFAULT_MODELS,
372
+ SEVERITY_LEVELS,
342
373
  UnsupportedProviderError,
343
374
  createLLMClient,
344
375
  createReviewConfig,
376
+ filterIssuesBySeverity,
345
377
  resolveApiKey,
346
378
  reviewIssueSchema,
347
379
  reviewResponseSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@content-reviewer/core",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Library for reviewing written content using LLMs",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",