@content-reviewer/core 0.0.3 → 0.0.4

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
@@ -46,6 +46,7 @@ type ReviewConfig = Readonly<{
46
46
  instruction?: string;
47
47
  language: Language;
48
48
  llm: LLMConfig;
49
+ severityLevel?: IssueSeverity;
49
50
  }>;
50
51
  type IssueSeverity = 'error' | 'warning' | 'suggestion';
51
52
  type ReviewIssue = Readonly<{
@@ -66,6 +67,7 @@ type ReviewConfigInput = Readonly<{
66
67
  instruction?: string;
67
68
  language?: Language;
68
69
  llm?: Partial<LLMConfig>;
70
+ severityLevel?: IssueSeverity;
69
71
  }>;
70
72
  declare const PROVIDER_DEFAULT_MODELS: Record<LLMProvider, string>;
71
73
  declare const DEFAULT_LLM_CONFIG: LLMConfig;
@@ -89,14 +91,13 @@ declare class ContentReviewer {
89
91
  constructor(config: ReviewConfig);
90
92
  review(document: Document): Promise<ReviewResult>;
91
93
  private runLLMReview;
92
- private generateSummary;
93
94
  private buildSystemPrompt;
94
95
  private buildUserPrompt;
95
96
  private findFirstMatchingLineNumber;
96
97
  }
97
98
 
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";
99
+ 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";
100
+ 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
101
 
101
102
  declare class ContentReviewerError extends Error {
102
103
  constructor(message: string);
@@ -118,4 +119,8 @@ declare const ENV_VARS: {
118
119
  readonly GOOGLE_API_KEY: "GOOGLE_API_KEY";
119
120
  };
120
121
 
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 };
122
+ declare const SEVERITY_LEVELS: Readonly<Record<IssueSeverity, number>>;
123
+ declare const DEFAULT_SEVERITY_LEVEL: IssueSeverity;
124
+ declare function filterIssuesBySeverity(issues: readonly ReviewIssue[], minLevel: IssueSeverity): ReviewIssue[];
125
+
126
+ 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
@@ -46,6 +46,7 @@ type ReviewConfig = Readonly<{
46
46
  instruction?: string;
47
47
  language: Language;
48
48
  llm: LLMConfig;
49
+ severityLevel?: IssueSeverity;
49
50
  }>;
50
51
  type IssueSeverity = 'error' | 'warning' | 'suggestion';
51
52
  type ReviewIssue = Readonly<{
@@ -66,6 +67,7 @@ type ReviewConfigInput = Readonly<{
66
67
  instruction?: string;
67
68
  language?: Language;
68
69
  llm?: Partial<LLMConfig>;
70
+ severityLevel?: IssueSeverity;
69
71
  }>;
70
72
  declare const PROVIDER_DEFAULT_MODELS: Record<LLMProvider, string>;
71
73
  declare const DEFAULT_LLM_CONFIG: LLMConfig;
@@ -89,14 +91,13 @@ declare class ContentReviewer {
89
91
  constructor(config: ReviewConfig);
90
92
  review(document: Document): Promise<ReviewResult>;
91
93
  private runLLMReview;
92
- private generateSummary;
93
94
  private buildSystemPrompt;
94
95
  private buildUserPrompt;
95
96
  private findFirstMatchingLineNumber;
96
97
  }
97
98
 
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";
99
+ 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";
100
+ 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
101
 
101
102
  declare class ContentReviewerError extends Error {
102
103
  constructor(message: string);
@@ -118,4 +119,8 @@ declare const ENV_VARS: {
118
119
  readonly GOOGLE_API_KEY: "GOOGLE_API_KEY";
119
120
  };
120
121
 
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 };
122
+ declare const SEVERITY_LEVELS: Readonly<Record<IssueSeverity, number>>;
123
+ declare const DEFAULT_SEVERITY_LEVEL: IssueSeverity;
124
+ declare function filterIssuesBySeverity(issues: readonly ReviewIssue[], minLevel: IssueSeverity): ReviewIssue[];
125
+
126
+ 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,
@@ -91,6 +94,20 @@ var MissingApiKeyError = class extends ContentReviewerError {
91
94
  }
92
95
  };
93
96
 
97
+ // src/filter.ts
98
+ var SEVERITY_LEVELS = {
99
+ error: 3,
100
+ warning: 2,
101
+ suggestion: 1
102
+ };
103
+ var DEFAULT_SEVERITY_LEVEL = Object.keys(SEVERITY_LEVELS).reduce(
104
+ (min, key) => SEVERITY_LEVELS[key] < SEVERITY_LEVELS[min] ? key : min
105
+ );
106
+ function filterIssuesBySeverity(issues, minLevel) {
107
+ const minLevelValue = SEVERITY_LEVELS[minLevel];
108
+ return issues.filter((issue) => SEVERITY_LEVELS[issue.severity] >= minLevelValue);
109
+ }
110
+
94
111
  // src/config.ts
95
112
  var PROVIDER_DEFAULT_MODELS = {
96
113
  openai: "gpt-4.1-mini",
@@ -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,48 +239,80 @@ 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
292
+ function getIncludedLevels(minLevel) {
293
+ const minValue = SEVERITY_LEVELS[minLevel];
294
+ return Object.keys(SEVERITY_LEVELS).filter((level) => SEVERITY_LEVELS[level] >= minValue).sort((a, b) => SEVERITY_LEVELS[b] - SEVERITY_LEVELS[a]);
295
+ }
296
+ function buildSummaryInstruction(minLevel, language) {
297
+ const includedLevels = getIncludedLevels(minLevel);
298
+ const formatLevels = (levels) => levels.map((l) => `"${l}"`).join(", ");
299
+ if (language === "ja") {
300
+ return `
301
+ \u91CD\u8981: \u554F\u984C\u70B9(issues)\u306F\u5168\u3066\u9069\u5207\u306Aseverity\u3067\u5831\u544A\u3057\u3066\u304F\u3060\u3055\u3044\u3002
302
+ \u305F\u3060\u3057\u3001\u7DCF\u8A55(summary)\u306F ${formatLevels(includedLevels)} \u306E\u554F\u984C\u306E\u307F\u306B\u57FA\u3065\u3044\u3066\u8A18\u8FF0\u3057\u3066\u304F\u3060\u3055\u3044\u3002
303
+ `;
304
+ }
305
+ return `
306
+ Important: Report all issues with their appropriate severity levels.
307
+ However, the summary should only reference issues with severity ${formatLevels(includedLevels)}.
308
+ `;
309
+ }
254
310
  var allPrompts = {
255
311
  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
- buildSystemPrompt: ({ instruction }) => {
258
- const instructions = instruction || DEFAULT_INSTRUCTION_JA;
259
- return `${instructions}
312
+ buildSystemPrompt: ({ instruction, severityLevel }) => {
313
+ const instructions = (instruction || DEFAULT_INSTRUCTION_JA).trimEnd() + "\n";
314
+ const summaryInstruction = severityLevel ? buildSummaryInstruction(severityLevel, "ja").trim() + "\n" : "";
315
+ return `${instructions}${summaryInstruction}
260
316
  \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
317
  - issues: \u898B\u3064\u304B\u3063\u305F\u554F\u984C\u70B9\u306E\u914D\u5217
262
318
  - severity: \u6DF1\u523B\u5EA6
@@ -269,17 +325,18 @@ var allPrompts = {
269
325
  - summary: \u5168\u4F53\u7684\u306A\u7DCF\u8A55\uFF082-3\u6587\u7A0B\u5EA6\uFF09
270
326
 
271
327
  \u6CE8\u610F\uFF1A
328
+ - \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
329
  - lineNumber\u306F\u4E0D\u8981\u3067\u3059\u3002matchText\u306E\u307F\u3092\u63D0\u4F9B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
273
330
  - \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
331
  `;
275
332
  },
276
- buildUserPrompt: () => "\u4EE5\u4E0B\u306E\u8A18\u4E8B\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A\n\n---\n"
333
+ buildUserPrompt: () => "\u4EE5\u4E0B\u306E\u30C6\u30AD\u30B9\u30C8\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A\n\n\n"
277
334
  },
278
335
  en: {
279
- generateSummary: (errorCount, warningCount) => `Review completed. Found ${errorCount} errors and ${warningCount} warnings.`,
280
- buildSystemPrompt: ({ instruction }) => {
281
- const instructions = instruction || DEFAULT_INSTRUCTION_EN;
282
- return `${instructions}
336
+ buildSystemPrompt: ({ instruction, severityLevel }) => {
337
+ const instructions = (instruction || DEFAULT_INSTRUCTION_EN).trimEnd() + "\n";
338
+ const summaryInstruction = severityLevel ? buildSummaryInstruction(severityLevel, "en").trim() + "\n" : "";
339
+ return `${instructions}${summaryInstruction}
283
340
  Provide the review results in English with the following JSON structure:
284
341
  - issues: Array of found issues
285
342
  - severity: Severity level
@@ -292,11 +349,12 @@ Provide the review results in English with the following JSON structure:
292
349
  - summary: Overall assessment (2-3 sentences)
293
350
 
294
351
  Note:
352
+ - Return valid JSON only (do not wrap in markdown code fences or add extra text).
295
353
  - Do not provide lineNumber. Only provide matchText.
296
354
  - Provide constructive and specific feedback.
297
355
  `;
298
356
  },
299
- buildUserPrompt: () => "Please review the following article:\n\n---\n"
357
+ buildUserPrompt: () => "Please review the following text:\n\n\n"
300
358
  }
301
359
  };
302
360
  function getLanguagePrompts(language) {
@@ -313,11 +371,11 @@ var ContentReviewer = class {
313
371
  }
314
372
  async review(document) {
315
373
  const llmResult = await this.runLLMReview(document);
316
- const summary = llmResult.summary || this.generateSummary(llmResult.issues);
374
+ const issues = this.config.severityLevel ? filterIssuesBySeverity(llmResult.issues, this.config.severityLevel) : llmResult.issues;
317
375
  return {
318
376
  source: document.source,
319
- issues: llmResult.issues,
320
- summary,
377
+ issues,
378
+ summary: llmResult.summary,
321
379
  reviewedAt: /* @__PURE__ */ new Date()
322
380
  };
323
381
  }
@@ -336,22 +394,16 @@ var ContentReviewer = class {
336
394
  summary: reviewData.summary
337
395
  };
338
396
  }
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);
344
- }
345
397
  buildSystemPrompt() {
346
- const { instruction, language } = this.config;
398
+ const { instruction, language, severityLevel } = this.config;
347
399
  const { buildSystemPrompt } = getLanguagePrompts(language);
348
- return buildSystemPrompt({ instruction });
400
+ return buildSystemPrompt({ instruction, severityLevel });
349
401
  }
350
402
  buildUserPrompt(document) {
351
403
  const { language } = this.config;
352
404
  const { buildUserPrompt } = getLanguagePrompts(language);
353
405
  const prompt = buildUserPrompt();
354
- return prompt + document.rawContent + "\n---";
406
+ return prompt + document.rawContent;
355
407
  }
356
408
  findFirstMatchingLineNumber(rawContent, matchText) {
357
409
  const index = rawContent.indexOf(matchText);
@@ -379,13 +431,16 @@ var ContentReviewer = class {
379
431
  DEFAULT_INSTRUCTION_EN,
380
432
  DEFAULT_INSTRUCTION_JA,
381
433
  DEFAULT_LLM_CONFIG,
434
+ DEFAULT_SEVERITY_LEVEL,
382
435
  ENV_VARS,
383
436
  LLMError,
384
437
  MissingApiKeyError,
385
438
  PROVIDER_DEFAULT_MODELS,
439
+ SEVERITY_LEVELS,
386
440
  UnsupportedProviderError,
387
441
  createLLMClient,
388
442
  createReviewConfig,
443
+ filterIssuesBySeverity,
389
444
  resolveApiKey,
390
445
  reviewIssueSchema,
391
446
  reviewResponseSchema,
package/dist/index.mjs CHANGED
@@ -48,6 +48,20 @@ var MissingApiKeyError = class extends ContentReviewerError {
48
48
  }
49
49
  };
50
50
 
51
+ // src/filter.ts
52
+ var SEVERITY_LEVELS = {
53
+ error: 3,
54
+ warning: 2,
55
+ suggestion: 1
56
+ };
57
+ var DEFAULT_SEVERITY_LEVEL = Object.keys(SEVERITY_LEVELS).reduce(
58
+ (min, key) => SEVERITY_LEVELS[key] < SEVERITY_LEVELS[min] ? key : min
59
+ );
60
+ function filterIssuesBySeverity(issues, minLevel) {
61
+ const minLevelValue = SEVERITY_LEVELS[minLevel];
62
+ return issues.filter((issue) => SEVERITY_LEVELS[issue.severity] >= minLevelValue);
63
+ }
64
+
51
65
  // src/config.ts
52
66
  var PROVIDER_DEFAULT_MODELS = {
53
67
  openai: "gpt-4.1-mini",
@@ -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,48 +193,80 @@ 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
246
+ function getIncludedLevels(minLevel) {
247
+ const minValue = SEVERITY_LEVELS[minLevel];
248
+ return Object.keys(SEVERITY_LEVELS).filter((level) => SEVERITY_LEVELS[level] >= minValue).sort((a, b) => SEVERITY_LEVELS[b] - SEVERITY_LEVELS[a]);
249
+ }
250
+ function buildSummaryInstruction(minLevel, language) {
251
+ const includedLevels = getIncludedLevels(minLevel);
252
+ const formatLevels = (levels) => levels.map((l) => `"${l}"`).join(", ");
253
+ if (language === "ja") {
254
+ return `
255
+ \u91CD\u8981: \u554F\u984C\u70B9(issues)\u306F\u5168\u3066\u9069\u5207\u306Aseverity\u3067\u5831\u544A\u3057\u3066\u304F\u3060\u3055\u3044\u3002
256
+ \u305F\u3060\u3057\u3001\u7DCF\u8A55(summary)\u306F ${formatLevels(includedLevels)} \u306E\u554F\u984C\u306E\u307F\u306B\u57FA\u3065\u3044\u3066\u8A18\u8FF0\u3057\u3066\u304F\u3060\u3055\u3044\u3002
257
+ `;
258
+ }
259
+ return `
260
+ Important: Report all issues with their appropriate severity levels.
261
+ However, the summary should only reference issues with severity ${formatLevels(includedLevels)}.
262
+ `;
263
+ }
211
264
  var allPrompts = {
212
265
  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
- buildSystemPrompt: ({ instruction }) => {
215
- const instructions = instruction || DEFAULT_INSTRUCTION_JA;
216
- return `${instructions}
266
+ buildSystemPrompt: ({ instruction, severityLevel }) => {
267
+ const instructions = (instruction || DEFAULT_INSTRUCTION_JA).trimEnd() + "\n";
268
+ const summaryInstruction = severityLevel ? buildSummaryInstruction(severityLevel, "ja").trim() + "\n" : "";
269
+ return `${instructions}${summaryInstruction}
217
270
  \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
271
  - issues: \u898B\u3064\u304B\u3063\u305F\u554F\u984C\u70B9\u306E\u914D\u5217
219
272
  - severity: \u6DF1\u523B\u5EA6
@@ -226,17 +279,18 @@ var allPrompts = {
226
279
  - summary: \u5168\u4F53\u7684\u306A\u7DCF\u8A55\uFF082-3\u6587\u7A0B\u5EA6\uFF09
227
280
 
228
281
  \u6CE8\u610F\uFF1A
282
+ - \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
283
  - lineNumber\u306F\u4E0D\u8981\u3067\u3059\u3002matchText\u306E\u307F\u3092\u63D0\u4F9B\u3057\u3066\u304F\u3060\u3055\u3044\u3002
230
284
  - \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
285
  `;
232
286
  },
233
- buildUserPrompt: () => "\u4EE5\u4E0B\u306E\u8A18\u4E8B\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A\n\n---\n"
287
+ buildUserPrompt: () => "\u4EE5\u4E0B\u306E\u30C6\u30AD\u30B9\u30C8\u3092\u30EC\u30D3\u30E5\u30FC\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A\n\n\n"
234
288
  },
235
289
  en: {
236
- generateSummary: (errorCount, warningCount) => `Review completed. Found ${errorCount} errors and ${warningCount} warnings.`,
237
- buildSystemPrompt: ({ instruction }) => {
238
- const instructions = instruction || DEFAULT_INSTRUCTION_EN;
239
- return `${instructions}
290
+ buildSystemPrompt: ({ instruction, severityLevel }) => {
291
+ const instructions = (instruction || DEFAULT_INSTRUCTION_EN).trimEnd() + "\n";
292
+ const summaryInstruction = severityLevel ? buildSummaryInstruction(severityLevel, "en").trim() + "\n" : "";
293
+ return `${instructions}${summaryInstruction}
240
294
  Provide the review results in English with the following JSON structure:
241
295
  - issues: Array of found issues
242
296
  - severity: Severity level
@@ -249,11 +303,12 @@ Provide the review results in English with the following JSON structure:
249
303
  - summary: Overall assessment (2-3 sentences)
250
304
 
251
305
  Note:
306
+ - Return valid JSON only (do not wrap in markdown code fences or add extra text).
252
307
  - Do not provide lineNumber. Only provide matchText.
253
308
  - Provide constructive and specific feedback.
254
309
  `;
255
310
  },
256
- buildUserPrompt: () => "Please review the following article:\n\n---\n"
311
+ buildUserPrompt: () => "Please review the following text:\n\n\n"
257
312
  }
258
313
  };
259
314
  function getLanguagePrompts(language) {
@@ -270,11 +325,11 @@ var ContentReviewer = class {
270
325
  }
271
326
  async review(document) {
272
327
  const llmResult = await this.runLLMReview(document);
273
- const summary = llmResult.summary || this.generateSummary(llmResult.issues);
328
+ const issues = this.config.severityLevel ? filterIssuesBySeverity(llmResult.issues, this.config.severityLevel) : llmResult.issues;
274
329
  return {
275
330
  source: document.source,
276
- issues: llmResult.issues,
277
- summary,
331
+ issues,
332
+ summary: llmResult.summary,
278
333
  reviewedAt: /* @__PURE__ */ new Date()
279
334
  };
280
335
  }
@@ -293,22 +348,16 @@ var ContentReviewer = class {
293
348
  summary: reviewData.summary
294
349
  };
295
350
  }
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);
301
- }
302
351
  buildSystemPrompt() {
303
- const { instruction, language } = this.config;
352
+ const { instruction, language, severityLevel } = this.config;
304
353
  const { buildSystemPrompt } = getLanguagePrompts(language);
305
- return buildSystemPrompt({ instruction });
354
+ return buildSystemPrompt({ instruction, severityLevel });
306
355
  }
307
356
  buildUserPrompt(document) {
308
357
  const { language } = this.config;
309
358
  const { buildUserPrompt } = getLanguagePrompts(language);
310
359
  const prompt = buildUserPrompt();
311
- return prompt + document.rawContent + "\n---";
360
+ return prompt + document.rawContent;
312
361
  }
313
362
  findFirstMatchingLineNumber(rawContent, matchText) {
314
363
  const index = rawContent.indexOf(matchText);
@@ -335,13 +384,16 @@ export {
335
384
  DEFAULT_INSTRUCTION_EN,
336
385
  DEFAULT_INSTRUCTION_JA,
337
386
  DEFAULT_LLM_CONFIG,
387
+ DEFAULT_SEVERITY_LEVEL,
338
388
  ENV_VARS,
339
389
  LLMError,
340
390
  MissingApiKeyError,
341
391
  PROVIDER_DEFAULT_MODELS,
392
+ SEVERITY_LEVELS,
342
393
  UnsupportedProviderError,
343
394
  createLLMClient,
344
395
  createReviewConfig,
396
+ filterIssuesBySeverity,
345
397
  resolveApiKey,
346
398
  reviewIssueSchema,
347
399
  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.4",
4
4
  "description": "Library for reviewing written content using LLMs",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",