@bonginkan/maria 3.1.4 → 3.1.6

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.
@@ -11757,6 +11757,2522 @@ var init_ai_response_tetris_template = __esm({
11757
11757
  }
11758
11758
  });
11759
11759
 
11760
+ // src/services/ai-response/intent.ts
11761
+ function analyzeIntent(userInputRaw, recentText = "") {
11762
+ const input3 = userInputRaw.trim();
11763
+ const low = input3.toLowerCase();
11764
+ const combinedContext = (recentText + " " + input3).toLowerCase();
11765
+ if (low.includes("tetris") || input3.includes("\u30C6\u30C8\u30EA\u30B9")) {
11766
+ return {
11767
+ type: "TETRIS_REQUEST",
11768
+ confidence: 0.95,
11769
+ detail: "User explicitly requested Tetris game"
11770
+ };
11771
+ }
11772
+ if (summaryHints.some((hint) => low.includes(hint))) {
11773
+ return {
11774
+ type: "SUMMARIZE",
11775
+ confidence: 0.9,
11776
+ detail: "User wants a summary of the conversation"
11777
+ };
11778
+ }
11779
+ if (recentText && continuationHints.some(
11780
+ (hint) => low.includes(hint) || recentText.toLowerCase().includes(hint)
11781
+ )) {
11782
+ return {
11783
+ type: "CONTINUATION",
11784
+ confidence: 0.85,
11785
+ detail: "User wants to continue previous topic"
11786
+ };
11787
+ }
11788
+ const isQuestion = low.endsWith("?") || low.endsWith("\uFF1F") || jaQuestionStarts.some((w) => input3.startsWith(w)) || [
11789
+ "what",
11790
+ "how",
11791
+ "why",
11792
+ "when",
11793
+ "where",
11794
+ "which",
11795
+ "who",
11796
+ "can you",
11797
+ "could you",
11798
+ "would you",
11799
+ "is it",
11800
+ "are there"
11801
+ ].some((w) => low.startsWith(w));
11802
+ if (isQuestion) {
11803
+ return {
11804
+ type: "QUESTION",
11805
+ confidence: 0.8,
11806
+ detail: "User is asking a question"
11807
+ };
11808
+ }
11809
+ const hasCodeSnippet = input3.includes("```") || input3.includes("`");
11810
+ const hasCodeHint = codeHints.some((hint) => combinedContext.includes(hint));
11811
+ const hasJaCodeTerm = jaCodeTerms.some((term) => input3.includes(term));
11812
+ const hasEnCodeTerms = [
11813
+ "implement",
11814
+ "create",
11815
+ "build",
11816
+ "write",
11817
+ "develop",
11818
+ "code",
11819
+ "function",
11820
+ "class",
11821
+ "method",
11822
+ "component"
11823
+ ].some((w) => low.includes(w));
11824
+ if (hasCodeSnippet || hasCodeHint || hasJaCodeTerm || hasEnCodeTerms) {
11825
+ return {
11826
+ type: "CODE_REQUEST",
11827
+ confidence: hasCodeSnippet ? 0.9 : 0.75,
11828
+ detail: "User wants code implementation or help"
11829
+ };
11830
+ }
11831
+ if (["refactor", "\u30EA\u30D5\u30A1\u30AF\u30BF", "\u6539\u5584", "\u6700\u9069\u5316", "optimize", "improve"].some((w) => low.includes(w))) {
11832
+ return {
11833
+ type: "REFACTOR",
11834
+ confidence: 0.7,
11835
+ detail: "User wants code refactoring or optimization"
11836
+ };
11837
+ }
11838
+ return {
11839
+ type: "GENERAL",
11840
+ confidence: 0.3,
11841
+ detail: "General conversation or unclear intent"
11842
+ };
11843
+ }
11844
+ function detectLanguage(input3) {
11845
+ const hasJapanese = /[ぁ-んァ-ヶー一-龥]/.test(input3);
11846
+ return hasJapanese ? "ja" : "en";
11847
+ }
11848
+ var jaQuestionStarts, codeHints, jaCodeTerms, continuationHints, summaryHints;
11849
+ var init_intent = __esm({
11850
+ "src/services/ai-response/intent.ts"() {
11851
+ jaQuestionStarts = [
11852
+ "\u4F55",
11853
+ "\u3069\u3046",
11854
+ "\u306A\u305C",
11855
+ "\u3044\u3064",
11856
+ "\u3069\u3053",
11857
+ "\u3069\u308C",
11858
+ "\u8AB0",
11859
+ "\u3067\u304D\u307E\u3059\u304B",
11860
+ "\u6559\u3048\u3066",
11861
+ "\u3042\u308A\u307E\u3059\u304B",
11862
+ "\u3067\u3057\u3087\u3046\u304B"
11863
+ ];
11864
+ codeHints = [
11865
+ "```",
11866
+ "function ",
11867
+ "class ",
11868
+ "const ",
11869
+ "let ",
11870
+ "import ",
11871
+ "export ",
11872
+ ".ts",
11873
+ ".tsx",
11874
+ ".js",
11875
+ ".jsx",
11876
+ ".json",
11877
+ ".py",
11878
+ ".java",
11879
+ ".go",
11880
+ ".rs",
11881
+ "HTML",
11882
+ "CSS",
11883
+ "SQL",
11884
+ "Dockerfile",
11885
+ "yaml",
11886
+ "yml"
11887
+ ];
11888
+ jaCodeTerms = [
11889
+ "\u5B9F\u88C5",
11890
+ "\u30B3\u30FC\u30C9",
11891
+ "\u95A2\u6570",
11892
+ "\u30AF\u30E9\u30B9",
11893
+ "\u30D3\u30EB\u30C9",
11894
+ "\u578B",
11895
+ "\u578B\u5B9A\u7FA9",
11896
+ "\u30C6\u30B9\u30C8",
11897
+ "\u30D7\u30ED\u30B0\u30E9\u30E0",
11898
+ "\u30B9\u30AF\u30EA\u30D7\u30C8",
11899
+ "\u30A2\u30D7\u30EA",
11900
+ "\u958B\u767A"
11901
+ ];
11902
+ continuationHints = [
11903
+ "\u7D9A\u304D",
11904
+ "\u3064\u3065\u304D",
11905
+ "\u7D9A\u884C",
11906
+ "\u5148\u307B\u3069\u306E",
11907
+ "\u524D\u56DE\u306E",
11908
+ "\u3055\u3063\u304D\u306E",
11909
+ "complete",
11910
+ "continue",
11911
+ "start",
11912
+ "give me",
11913
+ "finish",
11914
+ "proceed",
11915
+ "next",
11916
+ "then",
11917
+ "whole code"
11918
+ ];
11919
+ summaryHints = [
11920
+ "\u8981\u7D04",
11921
+ "\u307E\u3068\u3081",
11922
+ "\u30B5\u30DE\u30EA\u30FC",
11923
+ "\u307E\u3068\u3081\u3066",
11924
+ "\u6574\u7406",
11925
+ "summarize",
11926
+ "summary",
11927
+ "recap",
11928
+ "overview"
11929
+ ];
11930
+ }
11931
+ });
11932
+
11933
+ // src/services/ai-response/providers/base-provider.ts
11934
+ var BaseAIProvider2;
11935
+ var init_base_provider = __esm({
11936
+ "src/services/ai-response/providers/base-provider.ts"() {
11937
+ BaseAIProvider2 = class {
11938
+ config = {};
11939
+ initialized = false;
11940
+ availableModels = [];
11941
+ async initialize(config2) {
11942
+ this.config = config2;
11943
+ this.initialized = true;
11944
+ await this.performInitialization();
11945
+ }
11946
+ async streamCompletion(request2, onChunk) {
11947
+ const response2 = await this.generateCompletion(request2);
11948
+ const chunks = this.chunkResponse(response2.content);
11949
+ for (const chunk2 of chunks) {
11950
+ onChunk(chunk2);
11951
+ await this.delay(50);
11952
+ }
11953
+ return response2;
11954
+ }
11955
+ isAvailable() {
11956
+ return this.initialized && this.checkAvailability();
11957
+ }
11958
+ getAvailableModels() {
11959
+ return this.availableModels;
11960
+ }
11961
+ /**
11962
+ * Chunk response into smaller pieces for simulated streaming
11963
+ */
11964
+ chunkResponse(text2, chunkSize = 50) {
11965
+ const chunks = [];
11966
+ const words2 = text2.split(" ");
11967
+ for (let i2 = 0; i2 < words2.length; i2 += chunkSize) {
11968
+ chunks.push(words2.slice(i2, i2 + chunkSize).join(" ") + " ");
11969
+ }
11970
+ return chunks;
11971
+ }
11972
+ /**
11973
+ * Utility delay function
11974
+ */
11975
+ delay(ms) {
11976
+ return new Promise((resolve6) => setTimeout(resolve6, ms));
11977
+ }
11978
+ /**
11979
+ * Retry logic for API calls
11980
+ */
11981
+ async withRetry(operation, maxRetries = 3) {
11982
+ let lastError;
11983
+ for (let i2 = 0; i2 < maxRetries; i2++) {
11984
+ try {
11985
+ return await operation();
11986
+ } catch (error2) {
11987
+ lastError = error2;
11988
+ if (this.isNonRetryableError(error2)) {
11989
+ throw error2;
11990
+ }
11991
+ if (i2 < maxRetries - 1) {
11992
+ await this.delay(Math.pow(2, i2) * 1e3);
11993
+ }
11994
+ }
11995
+ }
11996
+ throw lastError || new Error("Operation failed after retries");
11997
+ }
11998
+ /**
11999
+ * Check if error should not be retried
12000
+ */
12001
+ isNonRetryableError(error2) {
12002
+ const message2 = error2?.message?.toLowerCase() || "";
12003
+ return message2.includes("invalid api key") || message2.includes("unauthorized") || message2.includes("forbidden");
12004
+ }
12005
+ };
12006
+ }
12007
+ });
12008
+
12009
+ // src/services/ai-response/providers/openai-provider.ts
12010
+ var OpenAIProvider2;
12011
+ var init_openai_provider2 = __esm({
12012
+ "src/services/ai-response/providers/openai-provider.ts"() {
12013
+ init_base_provider();
12014
+ OpenAIProvider2 = class extends BaseAIProvider2 {
12015
+ name = "OpenAI";
12016
+ apiEndpoint = "https://api.openai.com/v1/chat/completions";
12017
+ async performInitialization() {
12018
+ if (!this.config.defaultModel) {
12019
+ this.config.defaultModel = "gpt-3.5-turbo";
12020
+ }
12021
+ this.availableModels = [
12022
+ "gpt-4",
12023
+ "gpt-4-turbo-preview",
12024
+ "gpt-3.5-turbo",
12025
+ "gpt-3.5-turbo-16k"
12026
+ ];
12027
+ if (!this.config.apiKey) {
12028
+ console.warn("[OpenAI Provider] No API key provided - will use template responses");
12029
+ }
12030
+ }
12031
+ checkAvailability() {
12032
+ return true;
12033
+ }
12034
+ async generateCompletion(request2) {
12035
+ if (!this.config.apiKey) {
12036
+ return this.generateTemplateResponse(request2);
12037
+ }
12038
+ try {
12039
+ const response2 = await this.withRetry(
12040
+ () => this.callOpenAIAPI(request2)
12041
+ );
12042
+ return this.parseOpenAIResponse(response2);
12043
+ } catch (error2) {
12044
+ console.error("[OpenAI Provider] API call failed:", error2);
12045
+ return this.generateTemplateResponse(request2);
12046
+ }
12047
+ }
12048
+ async callOpenAIAPI(request2) {
12049
+ const payload = {
12050
+ model: request2.model || this.config.defaultModel,
12051
+ messages: request2.messages,
12052
+ temperature: request2.temperature ?? 0.7,
12053
+ max_tokens: request2.maxTokens ?? 2e3,
12054
+ stream: false
12055
+ };
12056
+ const response2 = await fetch(this.apiEndpoint, {
12057
+ method: "POST",
12058
+ headers: {
12059
+ "Content-Type": "application/json",
12060
+ "Authorization": `Bearer ${this.config.apiKey}`
12061
+ },
12062
+ body: JSON.stringify(payload)
12063
+ });
12064
+ if (!response2.ok) {
12065
+ const error2 = await response2.text();
12066
+ throw new Error(`OpenAI API error: ${response2.status} - ${error2}`);
12067
+ }
12068
+ return response2.json();
12069
+ }
12070
+ parseOpenAIResponse(response2) {
12071
+ const choice2 = response2.choices?.[0];
12072
+ if (!choice2) {
12073
+ throw new Error("Invalid OpenAI response format");
12074
+ }
12075
+ return {
12076
+ content: choice2.message?.content || "",
12077
+ model: response2.model || this.config.defaultModel || "gpt-3.5-turbo",
12078
+ usage: response2.usage ? {
12079
+ promptTokens: response2.usage.prompt_tokens,
12080
+ completionTokens: response2.usage.completion_tokens,
12081
+ totalTokens: response2.usage.total_tokens
12082
+ } : void 0,
12083
+ finishReason: choice2.finish_reason
12084
+ };
12085
+ }
12086
+ /**
12087
+ * Generate template response when API is unavailable
12088
+ */
12089
+ generateTemplateResponse(request2) {
12090
+ const lastMessage2 = request2.messages[request2.messages.length - 1];
12091
+ const input3 = lastMessage2?.content || "";
12092
+ const isJapanese = /[ぁ-んァ-ヶー一-龥]/.test(input3);
12093
+ let content2;
12094
+ if (input3.toLowerCase().includes("code") || input3.includes("\u5B9F\u88C5")) {
12095
+ content2 = isJapanese ? `\u30B3\u30FC\u30C9\u306E\u5B9F\u88C5\u306B\u3064\u3044\u3066\u304A\u624B\u4F1D\u3044\u3057\u307E\u3059\u3002
12096
+
12097
+ \`\`\`typescript
12098
+ // \u30B5\u30F3\u30D7\u30EB\u5B9F\u88C5
12099
+ function example() {
12100
+ console.log('Hello World');
12101
+ }
12102
+ \`\`\`
12103
+
12104
+ \u5B9F\u884C\u624B\u9806:
12105
+ 1. \u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210
12106
+ 2. \`node example.js\` \u3067\u5B9F\u884C` : `I'll help you with the code implementation.
12107
+
12108
+ \`\`\`typescript
12109
+ // Sample implementation
12110
+ function example() {
12111
+ console.log('Hello World');
12112
+ }
12113
+ \`\`\`
12114
+
12115
+ Run instructions:
12116
+ 1. Create the file
12117
+ 2. Run with \`node example.js\``;
12118
+ } else if (input3.includes("?") || input3.includes("\uFF1F")) {
12119
+ content2 = isJapanese ? `\u3054\u8CEA\u554F\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002\u300C${input3.substring(0, 50)}\u300D\u306B\u3064\u3044\u3066\u8AAC\u660E\u3057\u307E\u3059\u3002
12120
+
12121
+ \u8A73\u7D30\u306A\u56DE\u7B54\u3092\u3054\u5E0C\u671B\u306E\u5834\u5408\u306F\u3001\u5177\u4F53\u7684\u306A\u70B9\u3092\u304A\u77E5\u3089\u305B\u304F\u3060\u3055\u3044\u3002` : `Great question about "${input3.substring(0, 50)}". Let me explain.
12122
+
12123
+ For more details, please specify what aspect you'd like to focus on.`;
12124
+ } else {
12125
+ content2 = isJapanese ? `\u300C${input3.substring(0, 50)}\u300D\u306B\u3064\u3044\u3066\u5BFE\u5FDC\u3044\u305F\u3057\u307E\u3059\u3002
12126
+
12127
+ \u6B21\u306E\u30B9\u30C6\u30C3\u30D7:
12128
+ 1) \u8A73\u7D30\u3092\u78BA\u8A8D
12129
+ 2) \u5B9F\u88C5\u3092\u958B\u59CB
12130
+ 3) \u30C6\u30B9\u30C8\u3092\u5B9F\u884C
12131
+
12132
+ \u756A\u53F7\u3067\u304A\u9078\u3073\u304F\u3060\u3055\u3044\u3002` : `I'll help you with "${input3.substring(0, 50)}".
12133
+
12134
+ Next steps:
12135
+ 1) Review details
12136
+ 2) Start implementation
12137
+ 3) Run tests
12138
+
12139
+ Choose a number.`;
12140
+ }
12141
+ return {
12142
+ content: content2,
12143
+ model: "template",
12144
+ usage: {
12145
+ promptTokens: input3.length,
12146
+ completionTokens: content2.length,
12147
+ totalTokens: input3.length + content2.length
12148
+ },
12149
+ finishReason: "stop"
12150
+ };
12151
+ }
12152
+ async streamCompletion(request2, onChunk) {
12153
+ if (!this.config.apiKey) {
12154
+ return super.streamCompletion(request2, onChunk);
12155
+ }
12156
+ try {
12157
+ return super.streamCompletion(request2, onChunk);
12158
+ } catch (error2) {
12159
+ console.error("[OpenAI Provider] Stream failed:", error2);
12160
+ return super.streamCompletion(request2, onChunk);
12161
+ }
12162
+ }
12163
+ };
12164
+ }
12165
+ });
12166
+
12167
+ // src/services/ai-response/providers/anthropic-provider.ts
12168
+ var AnthropicProvider2;
12169
+ var init_anthropic_provider2 = __esm({
12170
+ "src/services/ai-response/providers/anthropic-provider.ts"() {
12171
+ init_base_provider();
12172
+ AnthropicProvider2 = class extends BaseAIProvider2 {
12173
+ name = "Anthropic";
12174
+ apiEndpoint = "https://api.anthropic.com/v1/messages";
12175
+ async performInitialization() {
12176
+ if (!this.config.defaultModel) {
12177
+ this.config.defaultModel = "claude-3-sonnet-20240229";
12178
+ }
12179
+ this.availableModels = [
12180
+ "claude-3-opus-20240229",
12181
+ "claude-3-sonnet-20240229",
12182
+ "claude-3-haiku-20240307",
12183
+ "claude-2.1",
12184
+ "claude-instant-1.2"
12185
+ ];
12186
+ if (!this.config.apiKey) {
12187
+ console.warn("[Anthropic Provider] No API key provided - will use template responses");
12188
+ }
12189
+ }
12190
+ checkAvailability() {
12191
+ return true;
12192
+ }
12193
+ async generateCompletion(request2) {
12194
+ if (!this.config.apiKey) {
12195
+ return this.generateTemplateResponse(request2);
12196
+ }
12197
+ try {
12198
+ const response2 = await this.withRetry(
12199
+ () => this.callAnthropicAPI(request2)
12200
+ );
12201
+ return this.parseAnthropicResponse(response2);
12202
+ } catch (error2) {
12203
+ console.error("[Anthropic Provider] API call failed:", error2);
12204
+ return this.generateTemplateResponse(request2);
12205
+ }
12206
+ }
12207
+ async callAnthropicAPI(request2) {
12208
+ const messages2 = request2.messages.map((msg2) => ({
12209
+ role: msg2.role === "system" ? "user" : msg2.role,
12210
+ content: msg2.content
12211
+ }));
12212
+ const systemMessage2 = request2.messages.find((m2) => m2.role === "system");
12213
+ const userMessages = request2.messages.filter((m2) => m2.role !== "system");
12214
+ const payload = {
12215
+ model: request2.model || this.config.defaultModel,
12216
+ messages: userMessages.map((msg2) => ({
12217
+ role: msg2.role === "user" ? "user" : "assistant",
12218
+ content: msg2.content
12219
+ })),
12220
+ max_tokens: request2.maxTokens ?? 2e3,
12221
+ temperature: request2.temperature ?? 0.7,
12222
+ ...systemMessage2 && { system: systemMessage2.content }
12223
+ };
12224
+ const response2 = await fetch(this.apiEndpoint, {
12225
+ method: "POST",
12226
+ headers: {
12227
+ "Content-Type": "application/json",
12228
+ "X-API-Key": this.config.apiKey,
12229
+ "anthropic-version": "2023-06-01"
12230
+ },
12231
+ body: JSON.stringify(payload)
12232
+ });
12233
+ if (!response2.ok) {
12234
+ const error2 = await response2.text();
12235
+ throw new Error(`Anthropic API error: ${response2.status} - ${error2}`);
12236
+ }
12237
+ return response2.json();
12238
+ }
12239
+ parseAnthropicResponse(response2) {
12240
+ if (!response2.content || !Array.isArray(response2.content)) {
12241
+ throw new Error("Invalid Anthropic response format");
12242
+ }
12243
+ const textContent = response2.content.filter((block) => block.type === "text").map((block) => block.text).join("\n");
12244
+ return {
12245
+ content: textContent,
12246
+ model: response2.model || this.config.defaultModel || "claude-3-sonnet",
12247
+ usage: response2.usage ? {
12248
+ promptTokens: response2.usage.input_tokens,
12249
+ completionTokens: response2.usage.output_tokens,
12250
+ totalTokens: response2.usage.input_tokens + response2.usage.output_tokens
12251
+ } : void 0,
12252
+ finishReason: response2.stop_reason
12253
+ };
12254
+ }
12255
+ /**
12256
+ * Generate template response when API is unavailable
12257
+ */
12258
+ generateTemplateResponse(request2) {
12259
+ const lastMessage2 = request2.messages[request2.messages.length - 1];
12260
+ const input3 = lastMessage2?.content || "";
12261
+ const isJapanese = /[ぁ-んァ-ヶー一-龥]/.test(input3);
12262
+ let content2;
12263
+ if (input3.toLowerCase().includes("analyze") || input3.includes("\u5206\u6790")) {
12264
+ content2 = isJapanese ? `\u300C${input3.substring(0, 50)}\u300D\u306E\u5206\u6790\u3092\u884C\u3044\u307E\u3059\u3002
12265
+
12266
+ ## \u5206\u6790\u7D50\u679C
12267
+
12268
+ ### 1. \u73FE\u72B6
12269
+ - \u30DD\u30A4\u30F3\u30C81
12270
+ - \u30DD\u30A4\u30F3\u30C82
12271
+
12272
+ ### 2. \u8AB2\u984C
12273
+ - \u8AB2\u984C1
12274
+ - \u8AB2\u984C2
12275
+
12276
+ ### 3. \u63D0\u6848
12277
+ - \u6539\u5584\u68481
12278
+ - \u6539\u5584\u68482
12279
+
12280
+ \u8A73\u7D30\u306A\u5206\u6790\u304C\u5FC5\u8981\u306A\u5834\u5408\u306F\u304A\u77E5\u3089\u305B\u304F\u3060\u3055\u3044\u3002` : `I'll analyze "${input3.substring(0, 50)}".
12281
+
12282
+ ## Analysis
12283
+
12284
+ ### 1. Current State
12285
+ - Point 1
12286
+ - Point 2
12287
+
12288
+ ### 2. Issues
12289
+ - Issue 1
12290
+ - Issue 2
12291
+
12292
+ ### 3. Recommendations
12293
+ - Solution 1
12294
+ - Solution 2
12295
+
12296
+ Let me know if you need deeper analysis.`;
12297
+ } else if (input3.toLowerCase().includes("explain") || input3.includes("\u8AAC\u660E")) {
12298
+ content2 = isJapanese ? `\u8A73\u3057\u304F\u8AAC\u660E\u3044\u305F\u3057\u307E\u3059\u3002
12299
+
12300
+ ## \u6982\u8981
12301
+ ${input3.substring(0, 50)}\u306B\u3064\u3044\u3066\u3001\u4EE5\u4E0B\u306E\u89B3\u70B9\u304B\u3089\u8AAC\u660E\u3057\u307E\u3059\uFF1A
12302
+
12303
+ 1. **\u57FA\u672C\u6982\u5FF5**
12304
+ - \u5B9A\u7FA9\u3068\u80CC\u666F
12305
+ - \u91CD\u8981\u6027
12306
+
12307
+ 2. **\u5B9F\u88C5\u8A73\u7D30**
12308
+ - \u5177\u4F53\u7684\u306A\u624B\u9806
12309
+ - \u30D9\u30B9\u30C8\u30D7\u30E9\u30AF\u30C6\u30A3\u30B9
12310
+
12311
+ 3. **\u6CE8\u610F\u70B9**
12312
+ - \u3088\u304F\u3042\u308B\u9593\u9055\u3044
12313
+ - \u56DE\u907F\u65B9\u6CD5
12314
+
12315
+ \u3055\u3089\u306B\u8A73\u3057\u3044\u60C5\u5831\u304C\u5FC5\u8981\u3067\u3057\u3087\u3046\u304B\uFF1F` : `Let me explain in detail.
12316
+
12317
+ ## Overview
12318
+ Regarding "${input3.substring(0, 50)}", I'll cover:
12319
+
12320
+ 1. **Core Concepts**
12321
+ - Definition and background
12322
+ - Importance
12323
+
12324
+ 2. **Implementation Details**
12325
+ - Step-by-step process
12326
+ - Best practices
12327
+
12328
+ 3. **Considerations**
12329
+ - Common pitfalls
12330
+ - How to avoid them
12331
+
12332
+ Would you like more specific information?`;
12333
+ } else {
12334
+ content2 = isJapanese ? `\u627F\u77E5\u3044\u305F\u3057\u307E\u3057\u305F\u3002\u300C${input3.substring(0, 50)}\u300D\u306B\u3064\u3044\u3066\u5BFE\u5FDC\u3057\u307E\u3059\u3002
12335
+
12336
+ \u69CB\u9020\u7684\u306B\u30A2\u30D7\u30ED\u30FC\u30C1\u3059\u308B\u305F\u3081\u3001\u4EE5\u4E0B\u306E\u624B\u9806\u3092\u63D0\u6848\u3057\u307E\u3059\uFF1A
12337
+
12338
+ 1. **\u8981\u4EF6\u306E\u660E\u78BA\u5316**
12339
+ 2. **\u5B9F\u88C5\u8A08\u753B\u306E\u7B56\u5B9A**
12340
+ 3. **\u6BB5\u968E\u7684\u306A\u5B9F\u88C5**
12341
+ 4. **\u30C6\u30B9\u30C8\u3068\u691C\u8A3C**
12342
+
12343
+ \u3069\u306E\u6BB5\u968E\u304B\u3089\u59CB\u3081\u307E\u3057\u3087\u3046\u304B\uFF1F` : `I understand. I'll help with "${input3.substring(0, 50)}".
12344
+
12345
+ For a structured approach, I suggest:
12346
+
12347
+ 1. **Clarify requirements**
12348
+ 2. **Create implementation plan**
12349
+ 3. **Phased implementation**
12350
+ 4. **Testing and validation**
12351
+
12352
+ Which phase shall we start with?`;
12353
+ }
12354
+ return {
12355
+ content: content2,
12356
+ model: "template-claude",
12357
+ usage: {
12358
+ promptTokens: input3.length,
12359
+ completionTokens: content2.length,
12360
+ totalTokens: input3.length + content2.length
12361
+ },
12362
+ finishReason: "stop"
12363
+ };
12364
+ }
12365
+ };
12366
+ }
12367
+ });
12368
+
12369
+ // src/services/ai-response/providers/template-provider.ts
12370
+ var TemplateProvider;
12371
+ var init_template_provider = __esm({
12372
+ "src/services/ai-response/providers/template-provider.ts"() {
12373
+ init_base_provider();
12374
+ TemplateProvider = class extends BaseAIProvider2 {
12375
+ name = "Template";
12376
+ async performInitialization() {
12377
+ this.availableModels = ["template-v1"];
12378
+ }
12379
+ checkAvailability() {
12380
+ return true;
12381
+ }
12382
+ async generateCompletion(request2) {
12383
+ const lastMessage2 = request2.messages[request2.messages.length - 1];
12384
+ const input3 = lastMessage2?.content || "";
12385
+ const context2 = request2.messages.slice(-5).map((m2) => m2.content).join("\n");
12386
+ const isJapanese = /[ぁ-んァ-ヶー一-龥]/.test(input3);
12387
+ const intent2 = this.analyzeIntent(input3, context2);
12388
+ const content2 = this.generateTemplateByIntent(intent2, input3, isJapanese);
12389
+ return {
12390
+ content: content2,
12391
+ model: "template-v1",
12392
+ usage: {
12393
+ promptTokens: input3.length,
12394
+ completionTokens: content2.length,
12395
+ totalTokens: input3.length + content2.length
12396
+ },
12397
+ finishReason: "stop"
12398
+ };
12399
+ }
12400
+ analyzeIntent(input3, context2) {
12401
+ const lower = input3.toLowerCase();
12402
+ const combined = (context2 + " " + input3).toLowerCase();
12403
+ if (lower.includes("implement") || lower.includes("\u5B9F\u88C5")) {
12404
+ return "implementation";
12405
+ }
12406
+ if (lower.includes("debug") || lower.includes("error") || lower.includes("\u30A8\u30E9\u30FC")) {
12407
+ return "debugging";
12408
+ }
12409
+ if (lower.includes("explain") || lower.includes("\u8AAC\u660E")) {
12410
+ return "explanation";
12411
+ }
12412
+ if (lower.includes("?") || lower.includes("\uFF1F")) {
12413
+ return "question";
12414
+ }
12415
+ if (combined.includes("continue") || combined.includes("\u7D9A")) {
12416
+ return "continuation";
12417
+ }
12418
+ if (lower.includes("test") || lower.includes("\u30C6\u30B9\u30C8")) {
12419
+ return "testing";
12420
+ }
12421
+ if (lower.includes("optimize") || lower.includes("\u6700\u9069\u5316")) {
12422
+ return "optimization";
12423
+ }
12424
+ return "general";
12425
+ }
12426
+ generateTemplateByIntent(intent2, input3, isJapanese) {
12427
+ const cleanInput = input3.substring(0, 80);
12428
+ switch (intent2) {
12429
+ case "implementation":
12430
+ return this.generateImplementationTemplate(cleanInput, isJapanese);
12431
+ case "debugging":
12432
+ return this.generateDebuggingTemplate(cleanInput, isJapanese);
12433
+ case "explanation":
12434
+ return this.generateExplanationTemplate(cleanInput, isJapanese);
12435
+ case "question":
12436
+ return this.generateQuestionTemplate(cleanInput, isJapanese);
12437
+ case "continuation":
12438
+ return this.generateContinuationTemplate(cleanInput, isJapanese);
12439
+ case "testing":
12440
+ return this.generateTestingTemplate(cleanInput, isJapanese);
12441
+ case "optimization":
12442
+ return this.generateOptimizationTemplate(cleanInput, isJapanese);
12443
+ default:
12444
+ return this.generateGeneralTemplate(cleanInput, isJapanese);
12445
+ }
12446
+ }
12447
+ generateImplementationTemplate(input3, isJapanese) {
12448
+ return isJapanese ? `\u300C${input3}\u300D\u306E\u5B9F\u88C5\u3092\u958B\u59CB\u3057\u307E\u3059\u3002
12449
+
12450
+ ## \u5B9F\u88C5\u8A08\u753B
12451
+
12452
+ ### 1. \u30A2\u30FC\u30AD\u30C6\u30AF\u30C1\u30E3\u8A2D\u8A08
12453
+ - \u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u69CB\u9020
12454
+ - \u30C7\u30FC\u30BF\u30D5\u30ED\u30FC
12455
+ - \u30A8\u30E9\u30FC\u30CF\u30F3\u30C9\u30EA\u30F3\u30B0
12456
+
12457
+ ### 2. \u57FA\u672C\u5B9F\u88C5
12458
+ \`\`\`typescript
12459
+ // \u30B5\u30F3\u30D7\u30EB\u5B9F\u88C5
12460
+ class Implementation {
12461
+ constructor(private config: Config) {}
12462
+
12463
+ async execute(): Promise<Result> {
12464
+ // \u5B9F\u88C5\u30ED\u30B8\u30C3\u30AF
12465
+ return this.process();
12466
+ }
12467
+ }
12468
+ \`\`\`
12469
+
12470
+ ### 3. \u5B9F\u884C\u624B\u9806
12471
+ 1. \u4F9D\u5B58\u95A2\u4FC2\u3092\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB: \`pnpm install\`
12472
+ 2. \u30D3\u30EB\u30C9: \`pnpm build\`
12473
+ 3. \u30C6\u30B9\u30C8\u5B9F\u884C: \`pnpm test\`
12474
+
12475
+ \u6B21\u306E\u30B9\u30C6\u30C3\u30D7\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A
12476
+ 1) \u30A8\u30E9\u30FC\u30CF\u30F3\u30C9\u30EA\u30F3\u30B0\u3092\u8FFD\u52A0
12477
+ 2) \u30C6\u30B9\u30C8\u30B1\u30FC\u30B9\u3092\u4F5C\u6210
12478
+ 3) \u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u6700\u9069\u5316` : `I'll implement "${input3}".
12479
+
12480
+ ## Implementation Plan
12481
+
12482
+ ### 1. Architecture Design
12483
+ - Component structure
12484
+ - Data flow
12485
+ - Error handling
12486
+
12487
+ ### 2. Base Implementation
12488
+ \`\`\`typescript
12489
+ // Sample implementation
12490
+ class Implementation {
12491
+ constructor(private config: Config) {}
12492
+
12493
+ async execute(): Promise<Result> {
12494
+ // Implementation logic
12495
+ return this.process();
12496
+ }
12497
+ }
12498
+ \`\`\`
12499
+
12500
+ ### 3. Run Instructions
12501
+ 1. Install dependencies: \`npm install\`
12502
+ 2. Build: \`npm run build\`
12503
+ 3. Run tests: \`npm test\`
12504
+
12505
+ Choose next step:
12506
+ 1) Add error handling
12507
+ 2) Create test cases
12508
+ 3) Optimize performance`;
12509
+ }
12510
+ generateDebuggingTemplate(input3, isJapanese) {
12511
+ return isJapanese ? `\u300C${input3}\u300D\u306E\u30C7\u30D0\u30C3\u30B0\u3092\u652F\u63F4\u3057\u307E\u3059\u3002
12512
+
12513
+ ## \u30C7\u30D0\u30C3\u30B0\u624B\u9806
12514
+
12515
+ ### 1. \u554F\u984C\u306E\u7279\u5B9A
12516
+ - \u30A8\u30E9\u30FC\u30E1\u30C3\u30BB\u30FC\u30B8\u306E\u78BA\u8A8D
12517
+ - \u30B9\u30BF\u30C3\u30AF\u30C8\u30EC\u30FC\u30B9\u306E\u5206\u6790
12518
+ - \u518D\u73FE\u6761\u4EF6\u306E\u78BA\u8A8D
12519
+
12520
+ ### 2. \u4E00\u822C\u7684\u306A\u539F\u56E0
12521
+ - \u578B\u306E\u4E0D\u4E00\u81F4
12522
+ - Null/Undefined\u53C2\u7167
12523
+ - \u975E\u540C\u671F\u51E6\u7406\u306E\u554F\u984C
12524
+ - \u4F9D\u5B58\u95A2\u4FC2\u306E\u4E0D\u8DB3
12525
+
12526
+ ### 3. \u89E3\u6C7A\u7B56
12527
+ \`\`\`typescript
12528
+ // \u30C7\u30D0\u30C3\u30B0\u30B3\u30FC\u30C9\u4F8B
12529
+ try {
12530
+ // \u554F\u984C\u306E\u3042\u308B\u30B3\u30FC\u30C9
12531
+ const result = await operation();
12532
+ console.log('Success:', result);
12533
+ } catch (error) {
12534
+ console.error('Error details:', error);
12535
+ // \u30A8\u30E9\u30FC\u51E6\u7406
12536
+ }
12537
+ \`\`\`
12538
+
12539
+ \u6B21\u306E\u78BA\u8A8D\u4E8B\u9805\uFF1A
12540
+ 1) \u30B3\u30F3\u30BD\u30FC\u30EB\u30ED\u30B0\u3092\u78BA\u8A8D
12541
+ 2) \u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8\u3092\u8A2D\u5B9A
12542
+ 3) \u5358\u4F53\u30C6\u30B9\u30C8\u3092\u5B9F\u884C` : `I'll help debug "${input3}".
12543
+
12544
+ ## Debug Process
12545
+
12546
+ ### 1. Problem Identification
12547
+ - Check error messages
12548
+ - Analyze stack trace
12549
+ - Verify reproduction steps
12550
+
12551
+ ### 2. Common Causes
12552
+ - Type mismatches
12553
+ - Null/Undefined references
12554
+ - Async handling issues
12555
+ - Missing dependencies
12556
+
12557
+ ### 3. Solution
12558
+ \`\`\`typescript
12559
+ // Debug code example
12560
+ try {
12561
+ // Problematic code
12562
+ const result = await operation();
12563
+ console.log('Success:', result);
12564
+ } catch (error) {
12565
+ console.error('Error details:', error);
12566
+ // Error handling
12567
+ }
12568
+ \`\`\`
12569
+
12570
+ Next checks:
12571
+ 1) Review console logs
12572
+ 2) Set breakpoints
12573
+ 3) Run unit tests`;
12574
+ }
12575
+ generateExplanationTemplate(input3, isJapanese) {
12576
+ return isJapanese ? `\u300C${input3}\u300D\u306B\u3064\u3044\u3066\u8A73\u3057\u304F\u8AAC\u660E\u3057\u307E\u3059\u3002
12577
+
12578
+ ## \u6982\u8981
12579
+ \u3053\u306E\u6982\u5FF5\u306F\u3001\u30BD\u30D5\u30C8\u30A6\u30A7\u30A2\u958B\u767A\u306B\u304A\u3044\u3066\u91CD\u8981\u306A\u5F79\u5272\u3092\u679C\u305F\u3057\u307E\u3059\u3002
12580
+
12581
+ ## \u8A73\u7D30\u8AAC\u660E
12582
+
12583
+ ### \u57FA\u672C\u539F\u7406
12584
+ - \u30B3\u30A2\u30B3\u30F3\u30BB\u30D7\u30C8
12585
+ - \u52D5\u4F5C\u539F\u7406
12586
+ - \u5229\u7528\u30B7\u30FC\u30F3
12587
+
12588
+ ### \u5B9F\u88C5\u4F8B
12589
+ \`\`\`typescript
12590
+ // \u6982\u5FF5\u306E\u5B9F\u88C5\u4F8B
12591
+ const example = {
12592
+ property: 'value',
12593
+ method: () => 'result'
12594
+ };
12595
+ \`\`\`
12596
+
12597
+ ### \u30E1\u30EA\u30C3\u30C8\u30FB\u30C7\u30E1\u30EA\u30C3\u30C8
12598
+ **\u30E1\u30EA\u30C3\u30C8:**
12599
+ - \u52B9\u7387\u7684\u306A\u51E6\u7406
12600
+ - \u4FDD\u5B88\u6027\u306E\u5411\u4E0A
12601
+
12602
+ **\u30C7\u30E1\u30EA\u30C3\u30C8:**
12603
+ - \u5B66\u7FD2\u30B3\u30B9\u30C8
12604
+ - \u521D\u671F\u8A2D\u5B9A\u306E\u8907\u96D1\u3055
12605
+
12606
+ \u3055\u3089\u306B\u8A73\u3057\u304F\u77E5\u308A\u305F\u3044\u70B9\u306F\u3042\u308A\u307E\u3059\u304B\uFF1F` : `Let me explain "${input3}" in detail.
12607
+
12608
+ ## Overview
12609
+ This concept plays an important role in software development.
12610
+
12611
+ ## Detailed Explanation
12612
+
12613
+ ### Core Principles
12614
+ - Core concepts
12615
+ - How it works
12616
+ - Use cases
12617
+
12618
+ ### Implementation Example
12619
+ \`\`\`typescript
12620
+ // Concept implementation
12621
+ const example = {
12622
+ property: 'value',
12623
+ method: () => 'result'
12624
+ };
12625
+ \`\`\`
12626
+
12627
+ ### Pros and Cons
12628
+ **Pros:**
12629
+ - Efficient processing
12630
+ - Better maintainability
12631
+
12632
+ **Cons:**
12633
+ - Learning curve
12634
+ - Initial setup complexity
12635
+
12636
+ Would you like to know more?`;
12637
+ }
12638
+ generateQuestionTemplate(input3, isJapanese) {
12639
+ return isJapanese ? `\u3054\u8CEA\u554F\u300C${input3}\u300D\u306B\u304A\u7B54\u3048\u3057\u307E\u3059\u3002
12640
+
12641
+ ## \u56DE\u7B54
12642
+
12643
+ \u7C21\u6F54\u306B\u7B54\u3048\u308B\u3068\u3001\u3053\u308C\u306F\u72B6\u6CC1\u3084\u8981\u4EF6\u306B\u3088\u3063\u3066\u7570\u306A\u308A\u307E\u3059\u3002
12644
+
12645
+ ### \u8A73\u7D30\u306A\u56DE\u7B54
12646
+
12647
+ 1. **\u6280\u8853\u7684\u89B3\u70B9**
12648
+ - \u5B9F\u88C5\u306E\u8907\u96D1\u3055
12649
+ - \u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u3078\u306E\u5F71\u97FF
12650
+
12651
+ 2. **\u5B9F\u7528\u7684\u89B3\u70B9**
12652
+ - \u4F7F\u7528\u983B\u5EA6
12653
+ - \u30E1\u30F3\u30C6\u30CA\u30F3\u30B9\u6027
12654
+
12655
+ 3. **\u30D9\u30B9\u30C8\u30D7\u30E9\u30AF\u30C6\u30A3\u30B9**
12656
+ - \u63A8\u5968\u3055\u308C\u308B\u65B9\u6CD5
12657
+ - \u907F\u3051\u308B\u3079\u304D\u30D1\u30BF\u30FC\u30F3
12658
+
12659
+ ### \u95A2\u9023\u60C5\u5831
12660
+ - \u53C2\u8003\u3068\u306A\u308B\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8
12661
+ - \u985E\u4F3C\u306E\u554F\u984C\u3068\u89E3\u6C7A\u7B56
12662
+
12663
+ \u4ED6\u306B\u78BA\u8A8D\u3057\u305F\u3044\u70B9\u306F\u3042\u308A\u307E\u3059\u304B\uFF1F` : `I'll answer your question: "${input3}"
12664
+
12665
+ ## Answer
12666
+
12667
+ In brief, this depends on the specific situation and requirements.
12668
+
12669
+ ### Detailed Response
12670
+
12671
+ 1. **Technical Perspective**
12672
+ - Implementation complexity
12673
+ - Performance impact
12674
+
12675
+ 2. **Practical Perspective**
12676
+ - Usage frequency
12677
+ - Maintainability
12678
+
12679
+ 3. **Best Practices**
12680
+ - Recommended approaches
12681
+ - Patterns to avoid
12682
+
12683
+ ### Related Information
12684
+ - Reference documentation
12685
+ - Similar issues and solutions
12686
+
12687
+ Any other questions?`;
12688
+ }
12689
+ generateContinuationTemplate(input3, isJapanese) {
12690
+ return isJapanese ? `\u524D\u56DE\u306E\u7D9A\u304D\u304B\u3089\u9032\u3081\u307E\u3059\u3002
12691
+
12692
+ ## \u9032\u884C\u72B6\u6CC1
12693
+ \u3053\u308C\u307E\u3067\u306E\u4F5C\u696D\u3092\u78BA\u8A8D\u3057\u307E\u3057\u305F\u3002
12694
+
12695
+ ## \u6B21\u306E\u30B9\u30C6\u30C3\u30D7
12696
+
12697
+ \u4EE5\u4E0B\u304B\u3089\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\uFF1A
12698
+
12699
+ 1) **\u5B9F\u88C5\u3092\u7D99\u7D9A**
12700
+ - \u6B8B\u308A\u306E\u6A5F\u80FD\u3092\u5B9F\u88C5
12701
+ - \u30A8\u30C3\u30B8\u30B1\u30FC\u30B9\u306E\u51E6\u7406
12702
+
12703
+ 2) **\u30C6\u30B9\u30C8\u3092\u8FFD\u52A0**
12704
+ - \u30E6\u30CB\u30C3\u30C8\u30C6\u30B9\u30C8
12705
+ - \u7D71\u5408\u30C6\u30B9\u30C8
12706
+
12707
+ 3) **\u30EA\u30D5\u30A1\u30AF\u30BF\u30EA\u30F3\u30B0**
12708
+ - \u30B3\u30FC\u30C9\u306E\u6574\u7406
12709
+ - \u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u6539\u5584
12710
+
12711
+ 4) **\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u4F5C\u6210**
12712
+ - API\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8
12713
+ - \u4F7F\u7528\u4F8B\u306E\u8FFD\u52A0
12714
+
12715
+ \u756A\u53F7\u3067\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\uFF081-4\uFF09\u3002` : `Let's continue from where we left off.
12716
+
12717
+ ## Progress
12718
+ I've reviewed our previous work.
12719
+
12720
+ ## Next Steps
12721
+
12722
+ Please choose:
12723
+
12724
+ 1) **Continue Implementation**
12725
+ - Remaining features
12726
+ - Edge case handling
12727
+
12728
+ 2) **Add Tests**
12729
+ - Unit tests
12730
+ - Integration tests
12731
+
12732
+ 3) **Refactoring**
12733
+ - Code organization
12734
+ - Performance improvements
12735
+
12736
+ 4) **Documentation**
12737
+ - API documentation
12738
+ - Usage examples
12739
+
12740
+ Choose a number (1-4).`;
12741
+ }
12742
+ generateTestingTemplate(input3, isJapanese) {
12743
+ return isJapanese ? `\u300C${input3}\u300D\u306E\u30C6\u30B9\u30C8\u3092\u4F5C\u6210\u3057\u307E\u3059\u3002
12744
+
12745
+ ## \u30C6\u30B9\u30C8\u6226\u7565
12746
+
12747
+ ### \u30E6\u30CB\u30C3\u30C8\u30C6\u30B9\u30C8
12748
+ \`\`\`typescript
12749
+ describe('Component', () => {
12750
+ it('should work correctly', () => {
12751
+ const result = component.method();
12752
+ expect(result).toBe(expected);
12753
+ });
12754
+
12755
+ it('should handle errors', () => {
12756
+ expect(() => component.invalid()).toThrow();
12757
+ });
12758
+ });
12759
+ \`\`\`
12760
+
12761
+ ### \u7D71\u5408\u30C6\u30B9\u30C8
12762
+ - API \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306E\u30C6\u30B9\u30C8
12763
+ - \u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u63A5\u7D9A\u306E\u30C6\u30B9\u30C8
12764
+ - \u5916\u90E8\u30B5\u30FC\u30D3\u30B9\u3068\u306E\u9023\u643A\u30C6\u30B9\u30C8
12765
+
12766
+ ### \u5B9F\u884C\u30B3\u30DE\u30F3\u30C9
12767
+ - \`pnpm test\` - \u5168\u30C6\u30B9\u30C8\u5B9F\u884C
12768
+ - \`pnpm test:watch\` - \u30A6\u30A9\u30C3\u30C1\u30E2\u30FC\u30C9
12769
+ - \`pnpm test:coverage\` - \u30AB\u30D0\u30EC\u30C3\u30B8\u30EC\u30DD\u30FC\u30C8
12770
+
12771
+ \u30C6\u30B9\u30C8\u30B1\u30FC\u30B9\u3092\u8FFD\u52A0\u3057\u307E\u3059\u304B\uFF1F` : `I'll create tests for "${input3}".
12772
+
12773
+ ## Test Strategy
12774
+
12775
+ ### Unit Tests
12776
+ \`\`\`typescript
12777
+ describe('Component', () => {
12778
+ it('should work correctly', () => {
12779
+ const result = component.method();
12780
+ expect(result).toBe(expected);
12781
+ });
12782
+
12783
+ it('should handle errors', () => {
12784
+ expect(() => component.invalid()).toThrow();
12785
+ });
12786
+ });
12787
+ \`\`\`
12788
+
12789
+ ### Integration Tests
12790
+ - API endpoint tests
12791
+ - Database connection tests
12792
+ - External service integration
12793
+
12794
+ ### Run Commands
12795
+ - \`npm test\` - Run all tests
12796
+ - \`npm test:watch\` - Watch mode
12797
+ - \`npm test:coverage\` - Coverage report
12798
+
12799
+ Add more test cases?`;
12800
+ }
12801
+ generateOptimizationTemplate(input3, isJapanese) {
12802
+ return isJapanese ? `\u300C${input3}\u300D\u306E\u6700\u9069\u5316\u3092\u884C\u3044\u307E\u3059\u3002
12803
+
12804
+ ## \u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u5206\u6790
12805
+
12806
+ ### \u73FE\u72B6\u306E\u8AB2\u984C
12807
+ - \u51E6\u7406\u6642\u9593: ~500ms
12808
+ - \u30E1\u30E2\u30EA\u4F7F\u7528\u91CF: ~50MB
12809
+ - CPU\u4F7F\u7528\u7387: \u9AD8
12810
+
12811
+ ### \u6700\u9069\u5316\u6226\u7565
12812
+
12813
+ 1. **\u30A2\u30EB\u30B4\u30EA\u30BA\u30E0\u306E\u6539\u5584**
12814
+ \`\`\`typescript
12815
+ // Before: O(n\xB2)
12816
+ for (let i = 0; i < n; i++) {
12817
+ for (let j = 0; j < n; j++) {
12818
+ // \u51E6\u7406
12819
+ }
12820
+ }
12821
+
12822
+ // After: O(n log n)
12823
+ items.sort((a, b) => a - b);
12824
+ // \u52B9\u7387\u7684\u306A\u51E6\u7406
12825
+ \`\`\`
12826
+
12827
+ 2. **\u30AD\u30E3\u30C3\u30B7\u30F3\u30B0**
12828
+ - \u30E1\u30E2\u30EA\u30AD\u30E3\u30C3\u30B7\u30E5\u306E\u5B9F\u88C5
12829
+ - \u8A08\u7B97\u7D50\u679C\u306E\u518D\u5229\u7528
12830
+
12831
+ 3. **\u975E\u540C\u671F\u51E6\u7406**
12832
+ - \u4E26\u5217\u51E6\u7406\u306E\u6D3B\u7528
12833
+ - \u30D0\u30C3\u30C1\u51E6\u7406\u306E\u5B9F\u88C5
12834
+
12835
+ \u6539\u5584\u52B9\u679C\u3092\u6E2C\u5B9A\u3057\u307E\u3059\u304B\uFF1F` : `I'll optimize "${input3}".
12836
+
12837
+ ## Performance Analysis
12838
+
12839
+ ### Current Issues
12840
+ - Processing time: ~500ms
12841
+ - Memory usage: ~50MB
12842
+ - CPU usage: High
12843
+
12844
+ ### Optimization Strategy
12845
+
12846
+ 1. **Algorithm Improvement**
12847
+ \`\`\`typescript
12848
+ // Before: O(n\xB2)
12849
+ for (let i = 0; i < n; i++) {
12850
+ for (let j = 0; j < n; j++) {
12851
+ // Process
12852
+ }
12853
+ }
12854
+
12855
+ // After: O(n log n)
12856
+ items.sort((a, b) => a - b);
12857
+ // Efficient processing
12858
+ \`\`\`
12859
+
12860
+ 2. **Caching**
12861
+ - Memory cache implementation
12862
+ - Result reuse
12863
+
12864
+ 3. **Async Processing**
12865
+ - Parallel processing
12866
+ - Batch processing
12867
+
12868
+ Measure improvements?`;
12869
+ }
12870
+ generateGeneralTemplate(input3, isJapanese) {
12871
+ return isJapanese ? `\u300C${input3}\u300D\u306B\u3064\u3044\u3066\u5BFE\u5FDC\u3044\u305F\u3057\u307E\u3059\u3002
12872
+
12873
+ \u3054\u8981\u671B\u3092\u6B63\u3057\u304F\u7406\u89E3\u3059\u308B\u305F\u3081\u3001\u4EE5\u4E0B\u304B\u3089\u6700\u3082\u8FD1\u3044\u3082\u306E\u3092\u304A\u9078\u3073\u304F\u3060\u3055\u3044\uFF1A
12874
+
12875
+ 1) **\u30B3\u30FC\u30C9\u5B9F\u88C5**
12876
+ - \u65B0\u6A5F\u80FD\u306E\u958B\u767A
12877
+ - \u65E2\u5B58\u30B3\u30FC\u30C9\u306E\u4FEE\u6B63
12878
+
12879
+ 2) **\u554F\u984C\u89E3\u6C7A**
12880
+ - \u30D0\u30B0\u4FEE\u6B63
12881
+ - \u30A8\u30E9\u30FC\u5BFE\u5FDC
12882
+
12883
+ 3) **\u8A2D\u8A08\u76F8\u8AC7**
12884
+ - \u30A2\u30FC\u30AD\u30C6\u30AF\u30C1\u30E3\u8A2D\u8A08
12885
+ - \u30D9\u30B9\u30C8\u30D7\u30E9\u30AF\u30C6\u30A3\u30B9
12886
+
12887
+ 4) **\u5B66\u7FD2\u30B5\u30DD\u30FC\u30C8**
12888
+ - \u6982\u5FF5\u306E\u8AAC\u660E
12889
+ - \u4F7F\u7528\u65B9\u6CD5\u306E\u89E3\u8AAC
12890
+
12891
+ \u756A\u53F7\u3067\u304A\u7B54\u3048\u304F\u3060\u3055\u3044\uFF081-4\uFF09\u3002` : `I'll help with "${input3}".
12892
+
12893
+ To better understand your needs, please choose:
12894
+
12895
+ 1) **Code Implementation**
12896
+ - New features
12897
+ - Code modifications
12898
+
12899
+ 2) **Problem Solving**
12900
+ - Bug fixes
12901
+ - Error resolution
12902
+
12903
+ 3) **Design Consultation**
12904
+ - Architecture design
12905
+ - Best practices
12906
+
12907
+ 4) **Learning Support**
12908
+ - Concept explanation
12909
+ - Usage guidance
12910
+
12911
+ Please reply with a number (1-4).`;
12912
+ }
12913
+ };
12914
+ }
12915
+ });
12916
+
12917
+ // src/services/ai-response/providers/provider-factory.ts
12918
+ var AIProviderFactory;
12919
+ var init_provider_factory = __esm({
12920
+ "src/services/ai-response/providers/provider-factory.ts"() {
12921
+ init_openai_provider2();
12922
+ init_anthropic_provider2();
12923
+ init_template_provider();
12924
+ AIProviderFactory = class _AIProviderFactory {
12925
+ static instance;
12926
+ providers = /* @__PURE__ */ new Map();
12927
+ currentProvider = "template";
12928
+ constructor() {
12929
+ }
12930
+ static getInstance() {
12931
+ if (!_AIProviderFactory.instance) {
12932
+ _AIProviderFactory.instance = new _AIProviderFactory();
12933
+ }
12934
+ return _AIProviderFactory.instance;
12935
+ }
12936
+ /**
12937
+ * Initialize a provider with configuration
12938
+ */
12939
+ async initializeProvider(type2, config2) {
12940
+ const provider2 = this.createProvider(type2);
12941
+ await provider2.initialize(config2);
12942
+ this.providers.set(type2, provider2);
12943
+ console.log(`[Provider Factory] Initialized ${type2} provider`);
12944
+ }
12945
+ /**
12946
+ * Create a provider instance
12947
+ */
12948
+ createProvider(type2) {
12949
+ switch (type2) {
12950
+ case "openai":
12951
+ return new OpenAIProvider2();
12952
+ case "anthropic":
12953
+ return new AnthropicProvider2();
12954
+ case "template":
12955
+ return new TemplateProvider();
12956
+ default:
12957
+ console.warn(`[Provider Factory] Unknown provider type: ${type2}, falling back to template`);
12958
+ return new TemplateProvider();
12959
+ }
12960
+ }
12961
+ /**
12962
+ * Get a specific provider
12963
+ */
12964
+ getProvider(type2) {
12965
+ const targetType = type2 || this.currentProvider;
12966
+ if (!this.providers.has(targetType) && targetType === "template") {
12967
+ const templateProvider = new TemplateProvider();
12968
+ templateProvider.initialize({}).catch(console.error);
12969
+ this.providers.set("template", templateProvider);
12970
+ }
12971
+ return this.providers.get(targetType);
12972
+ }
12973
+ /**
12974
+ * Get the active provider with fallback
12975
+ */
12976
+ async getActiveProvider() {
12977
+ let provider2 = this.getProvider(this.currentProvider);
12978
+ if (provider2?.isAvailable()) {
12979
+ return provider2;
12980
+ }
12981
+ const fallbackOrder = ["openai", "anthropic", "template"];
12982
+ for (const type2 of fallbackOrder) {
12983
+ provider2 = this.getProvider(type2);
12984
+ if (provider2?.isAvailable()) {
12985
+ console.log(`[Provider Factory] Falling back to ${type2} provider`);
12986
+ this.currentProvider = type2;
12987
+ return provider2;
12988
+ }
12989
+ }
12990
+ console.log("[Provider Factory] Using template provider as last resort");
12991
+ const templateProvider = new TemplateProvider();
12992
+ await templateProvider.initialize({});
12993
+ this.providers.set("template", templateProvider);
12994
+ this.currentProvider = "template";
12995
+ return templateProvider;
12996
+ }
12997
+ /**
12998
+ * Set the active provider
12999
+ */
13000
+ setActiveProvider(type2) {
13001
+ if (!this.providers.has(type2)) {
13002
+ throw new Error(`Provider ${type2} not initialized`);
13003
+ }
13004
+ this.currentProvider = type2;
13005
+ console.log(`[Provider Factory] Active provider set to ${type2}`);
13006
+ }
13007
+ /**
13008
+ * Initialize providers from environment variables
13009
+ */
13010
+ async initializeFromEnvironment() {
13011
+ const configs = [];
13012
+ if (process.env.OPENAI_API_KEY) {
13013
+ configs.push(["openai", {
13014
+ apiKey: process.env.OPENAI_API_KEY,
13015
+ defaultModel: process.env.OPENAI_MODEL || "gpt-3.5-turbo"
13016
+ }]);
13017
+ }
13018
+ if (process.env.ANTHROPIC_API_KEY) {
13019
+ configs.push(["anthropic", {
13020
+ apiKey: process.env.ANTHROPIC_API_KEY,
13021
+ defaultModel: process.env.ANTHROPIC_MODEL || "claude-3-sonnet-20240229"
13022
+ }]);
13023
+ }
13024
+ configs.push(["template", {}]);
13025
+ for (const [type2, config2] of configs) {
13026
+ try {
13027
+ await this.initializeProvider(type2, config2);
13028
+ } catch (error2) {
13029
+ console.error(`[Provider Factory] Failed to initialize ${type2}:`, error2);
13030
+ }
13031
+ }
13032
+ const preferredProvider = process.env.AI_PROVIDER || "template";
13033
+ if (this.providers.has(preferredProvider)) {
13034
+ this.setActiveProvider(preferredProvider);
13035
+ }
13036
+ }
13037
+ /**
13038
+ * Get list of available providers
13039
+ */
13040
+ getAvailableProviders() {
13041
+ return Array.from(this.providers.keys()).filter((type2) => {
13042
+ const provider2 = this.providers.get(type2);
13043
+ return provider2?.isAvailable();
13044
+ });
13045
+ }
13046
+ /**
13047
+ * Clear all providers (for testing)
13048
+ */
13049
+ clearProviders() {
13050
+ this.providers.clear();
13051
+ this.currentProvider = "template";
13052
+ }
13053
+ };
13054
+ }
13055
+ });
13056
+
13057
+ // src/services/ai-response/feature-flags.ts
13058
+ var FeatureFlagManager, featureFlags;
13059
+ var init_feature_flags = __esm({
13060
+ "src/services/ai-response/feature-flags.ts"() {
13061
+ FeatureFlagManager = class _FeatureFlagManager {
13062
+ static instance;
13063
+ flags;
13064
+ userHash = null;
13065
+ constructor() {
13066
+ this.flags = {
13067
+ useRealProviders: false,
13068
+ providerType: "template",
13069
+ enableStreaming: false,
13070
+ enableSafetyGuards: true,
13071
+ enableTelemetry: true,
13072
+ rolloutPercentage: 0
13073
+ };
13074
+ this.loadFromEnvironment();
13075
+ }
13076
+ static getInstance() {
13077
+ if (!_FeatureFlagManager.instance) {
13078
+ _FeatureFlagManager.instance = new _FeatureFlagManager();
13079
+ }
13080
+ return _FeatureFlagManager.instance;
13081
+ }
13082
+ /**
13083
+ * Load flags from environment variables
13084
+ */
13085
+ loadFromEnvironment() {
13086
+ const v3Enabled = process.env.AI_RESPONSE_V3 === "true";
13087
+ if (v3Enabled) {
13088
+ this.flags.useRealProviders = process.env.USE_REAL_AI_PROVIDERS === "true";
13089
+ this.flags.providerType = process.env.AI_PROVIDER || "template";
13090
+ this.flags.enableStreaming = process.env.ENABLE_STREAMING === "true";
13091
+ this.flags.rolloutPercentage = parseInt(process.env.AI_ROLLOUT_PERCENTAGE || "0", 10);
13092
+ }
13093
+ this.flags.enableSafetyGuards = process.env.DISABLE_SAFETY_GUARDS !== "true";
13094
+ this.flags.enableTelemetry = process.env.DISABLE_TELEMETRY !== "true";
13095
+ console.log("[Feature Flags] Loaded configuration:", this.flags);
13096
+ }
13097
+ /**
13098
+ * Check if a feature is enabled for the current user
13099
+ */
13100
+ isEnabled(feature) {
13101
+ if (feature === "useRealProviders" && this.flags.rolloutPercentage < 100) {
13102
+ return this.isInRolloutGroup();
13103
+ }
13104
+ return this.flags[feature];
13105
+ }
13106
+ /**
13107
+ * Get a flag value
13108
+ */
13109
+ getFlag(key2) {
13110
+ return this.flags[key2];
13111
+ }
13112
+ /**
13113
+ * Set a flag value (for testing)
13114
+ */
13115
+ setFlag(key2, value2) {
13116
+ this.flags[key2] = value2;
13117
+ console.log(`[Feature Flags] Updated ${key2} to ${value2}`);
13118
+ }
13119
+ /**
13120
+ * Set user identifier for consistent rollout
13121
+ */
13122
+ setUserIdentifier(userId) {
13123
+ this.userHash = this.hashString(userId);
13124
+ }
13125
+ /**
13126
+ * Check if current user is in rollout group
13127
+ */
13128
+ isInRolloutGroup() {
13129
+ if (!this.userHash) {
13130
+ return Math.random() * 100 < this.flags.rolloutPercentage;
13131
+ }
13132
+ const hashValue = parseInt(this.userHash.substring(0, 8), 16);
13133
+ const userPercentage = hashValue % 100;
13134
+ return userPercentage < this.flags.rolloutPercentage;
13135
+ }
13136
+ /**
13137
+ * Simple hash function for consistent user assignment
13138
+ */
13139
+ hashString(str) {
13140
+ let hash = 0;
13141
+ for (let i2 = 0; i2 < str.length; i2++) {
13142
+ const char = str.charCodeAt(i2);
13143
+ hash = (hash << 5) - hash + char;
13144
+ hash = hash & hash;
13145
+ }
13146
+ return Math.abs(hash).toString(16);
13147
+ }
13148
+ /**
13149
+ * Get configuration for AI response service
13150
+ */
13151
+ getAIResponseConfig() {
13152
+ return {
13153
+ useRealProviders: this.isEnabled("useRealProviders"),
13154
+ providerType: this.flags.providerType,
13155
+ enableStreaming: this.isEnabled("enableStreaming"),
13156
+ enableSafetyGuards: this.isEnabled("enableSafetyGuards"),
13157
+ enableTelemetry: this.isEnabled("enableTelemetry")
13158
+ };
13159
+ }
13160
+ /**
13161
+ * Reset to defaults (for testing)
13162
+ */
13163
+ reset() {
13164
+ this.flags = {
13165
+ useRealProviders: false,
13166
+ providerType: "template",
13167
+ enableStreaming: false,
13168
+ enableSafetyGuards: true,
13169
+ enableTelemetry: true,
13170
+ rolloutPercentage: 0
13171
+ };
13172
+ this.userHash = null;
13173
+ }
13174
+ };
13175
+ featureFlags = FeatureFlagManager.getInstance();
13176
+ }
13177
+ });
13178
+
13179
+ // src/services/ai-response/telemetry/telemetry-collector.ts
13180
+ var TelemetryCollector;
13181
+ var init_telemetry_collector = __esm({
13182
+ "src/services/ai-response/telemetry/telemetry-collector.ts"() {
13183
+ TelemetryCollector = class _TelemetryCollector {
13184
+ static instance;
13185
+ events = [];
13186
+ sessionId;
13187
+ flushInterval = null;
13188
+ aggregationInterval = null;
13189
+ metricsBuffer = /* @__PURE__ */ new Map();
13190
+ constructor() {
13191
+ this.sessionId = this.generateSessionId();
13192
+ this.startCollection();
13193
+ }
13194
+ static getInstance() {
13195
+ if (!_TelemetryCollector.instance) {
13196
+ _TelemetryCollector.instance = new _TelemetryCollector();
13197
+ }
13198
+ return _TelemetryCollector.instance;
13199
+ }
13200
+ /**
13201
+ * Start collecting metrics
13202
+ */
13203
+ startCollection() {
13204
+ this.flushInterval = setInterval(() => {
13205
+ this.flushEvents();
13206
+ }, 3e4);
13207
+ this.aggregationInterval = setInterval(() => {
13208
+ this.aggregateMetrics("minute");
13209
+ }, 6e4);
13210
+ console.log("[Telemetry] Collection started");
13211
+ }
13212
+ /**
13213
+ * Track intent decision
13214
+ */
13215
+ trackIntent(metric) {
13216
+ this.addEvent({
13217
+ timestamp: Date.now(),
13218
+ eventType: "intent_decided",
13219
+ sessionId: this.sessionId,
13220
+ data: metric
13221
+ });
13222
+ }
13223
+ /**
13224
+ * Track response generation
13225
+ */
13226
+ trackResponse(metric) {
13227
+ this.addEvent({
13228
+ timestamp: Date.now(),
13229
+ eventType: "response_generated",
13230
+ sessionId: this.sessionId,
13231
+ data: metric
13232
+ });
13233
+ if (!metric.fallback) {
13234
+ this.addEvent({
13235
+ timestamp: Date.now(),
13236
+ eventType: "provider_called",
13237
+ sessionId: this.sessionId,
13238
+ data: {
13239
+ provider: metric.provider,
13240
+ success: metric.success
13241
+ }
13242
+ });
13243
+ }
13244
+ }
13245
+ /**
13246
+ * Track safety violations
13247
+ */
13248
+ trackSafetyViolation(metric) {
13249
+ this.addEvent({
13250
+ timestamp: Date.now(),
13251
+ eventType: "safety_violation",
13252
+ sessionId: this.sessionId,
13253
+ data: metric
13254
+ });
13255
+ }
13256
+ /**
13257
+ * Track user feedback
13258
+ */
13259
+ trackUserFeedback(metric) {
13260
+ this.addEvent({
13261
+ timestamp: Date.now(),
13262
+ eventType: "user_feedback",
13263
+ sessionId: this.sessionId,
13264
+ data: metric
13265
+ });
13266
+ }
13267
+ /**
13268
+ * Track errors
13269
+ */
13270
+ trackError(error2, context2) {
13271
+ this.addEvent({
13272
+ timestamp: Date.now(),
13273
+ eventType: "error_occurred",
13274
+ sessionId: this.sessionId,
13275
+ data: {
13276
+ message: error2.message,
13277
+ stack: error2.stack,
13278
+ ...context2
13279
+ }
13280
+ });
13281
+ }
13282
+ /**
13283
+ * Add event to buffer
13284
+ */
13285
+ addEvent(event) {
13286
+ this.events.push(event);
13287
+ if (this.events.length >= 100) {
13288
+ this.flushEvents();
13289
+ }
13290
+ }
13291
+ /**
13292
+ * Flush events to storage/API
13293
+ */
13294
+ async flushEvents() {
13295
+ if (this.events.length === 0) return;
13296
+ const eventsToFlush = [...this.events];
13297
+ this.events = [];
13298
+ try {
13299
+ if (process.env.TELEMETRY_ENDPOINT) {
13300
+ await this.sendToEndpoint(eventsToFlush);
13301
+ } else {
13302
+ this.storeLocally(eventsToFlush);
13303
+ }
13304
+ } catch (error2) {
13305
+ console.error("[Telemetry] Failed to flush events:", error2);
13306
+ this.events.unshift(...eventsToFlush);
13307
+ }
13308
+ }
13309
+ /**
13310
+ * Send events to telemetry endpoint
13311
+ */
13312
+ async sendToEndpoint(events) {
13313
+ const endpoint = process.env.TELEMETRY_ENDPOINT;
13314
+ const apiKey2 = process.env.TELEMETRY_API_KEY;
13315
+ if (!endpoint) return;
13316
+ const response2 = await fetch(endpoint, {
13317
+ method: "POST",
13318
+ headers: {
13319
+ "Content-Type": "application/json",
13320
+ ...apiKey2 && { "Authorization": `Bearer ${apiKey2}` }
13321
+ },
13322
+ body: JSON.stringify({ events })
13323
+ });
13324
+ if (!response2.ok) {
13325
+ throw new Error(`Telemetry endpoint returned ${response2.status}`);
13326
+ }
13327
+ }
13328
+ /**
13329
+ * Store events locally (for development)
13330
+ */
13331
+ storeLocally(events) {
13332
+ const key2 = `metrics_${Date.now()}`;
13333
+ this.metricsBuffer.set(key2, this.calculateMetrics(events));
13334
+ if (this.metricsBuffer.size > 100) {
13335
+ const keys = Array.from(this.metricsBuffer.keys());
13336
+ this.metricsBuffer.delete(keys[0]);
13337
+ }
13338
+ }
13339
+ /**
13340
+ * Calculate metrics from events
13341
+ */
13342
+ calculateMetrics(events) {
13343
+ const now2 = Date.now();
13344
+ const metrics2 = {
13345
+ period: "minute",
13346
+ startTime: now2 - 6e4,
13347
+ endTime: now2,
13348
+ // Intent metrics
13349
+ intentCounts: {},
13350
+ intentAccuracy: 0,
13351
+ languageDistribution: {},
13352
+ // Response metrics
13353
+ totalResponses: 0,
13354
+ averageLatency: 0,
13355
+ p95Latency: 0,
13356
+ p99Latency: 0,
13357
+ providerDistribution: {},
13358
+ fallbackRate: 0,
13359
+ errorRate: 0,
13360
+ // Token usage
13361
+ totalTokens: 0,
13362
+ averageTokensPerRequest: 0,
13363
+ // Safety metrics
13364
+ safetyViolations: 0,
13365
+ violationTypes: {},
13366
+ // User satisfaction
13367
+ satisfactionRate: 0,
13368
+ feedbackCount: 0,
13369
+ feedbackDistribution: {}
13370
+ };
13371
+ const latencies = [];
13372
+ let totalTokens = 0;
13373
+ let feedbackPositive = 0;
13374
+ let feedbackTotal = 0;
13375
+ events.forEach((event) => {
13376
+ switch (event.eventType) {
13377
+ case "intent_decided":
13378
+ const intent2 = event.data;
13379
+ metrics2.intentCounts[intent2.type] = (metrics2.intentCounts[intent2.type] || 0) + 1;
13380
+ metrics2.languageDistribution[intent2.language] = (metrics2.languageDistribution[intent2.language] || 0) + 1;
13381
+ break;
13382
+ case "response_generated":
13383
+ const response2 = event.data;
13384
+ metrics2.totalResponses++;
13385
+ latencies.push(response2.latencyMs);
13386
+ metrics2.providerDistribution[response2.provider] = (metrics2.providerDistribution[response2.provider] || 0) + 1;
13387
+ if (response2.fallback) metrics2.fallbackRate++;
13388
+ if (!response2.success) metrics2.errorRate++;
13389
+ if (response2.tokenUsage) {
13390
+ totalTokens += response2.tokenUsage.total;
13391
+ }
13392
+ break;
13393
+ case "safety_violation":
13394
+ const safety = event.data;
13395
+ metrics2.safetyViolations++;
13396
+ metrics2.violationTypes[safety.violationType] = (metrics2.violationTypes[safety.violationType] || 0) + 1;
13397
+ break;
13398
+ case "user_feedback":
13399
+ const feedback = event.data;
13400
+ feedbackTotal++;
13401
+ if (feedback.rating === "positive") feedbackPositive++;
13402
+ metrics2.feedbackDistribution[feedback.rating] = (metrics2.feedbackDistribution[feedback.rating] || 0) + 1;
13403
+ break;
13404
+ }
13405
+ });
13406
+ if (latencies.length > 0) {
13407
+ latencies.sort((a2, b) => a2 - b);
13408
+ metrics2.averageLatency = latencies.reduce((a2, b) => a2 + b, 0) / latencies.length;
13409
+ metrics2.p95Latency = latencies[Math.floor(latencies.length * 0.95)] || 0;
13410
+ metrics2.p99Latency = latencies[Math.floor(latencies.length * 0.99)] || 0;
13411
+ }
13412
+ if (metrics2.totalResponses > 0) {
13413
+ metrics2.fallbackRate = metrics2.fallbackRate / metrics2.totalResponses;
13414
+ metrics2.errorRate = metrics2.errorRate / metrics2.totalResponses;
13415
+ metrics2.averageTokensPerRequest = totalTokens / metrics2.totalResponses;
13416
+ }
13417
+ if (feedbackTotal > 0) {
13418
+ metrics2.satisfactionRate = feedbackPositive / feedbackTotal;
13419
+ }
13420
+ metrics2.feedbackCount = feedbackTotal;
13421
+ metrics2.totalTokens = totalTokens;
13422
+ return metrics2;
13423
+ }
13424
+ /**
13425
+ * Aggregate metrics by period
13426
+ */
13427
+ aggregateMetrics(period) {
13428
+ const recentEvents = this.getRecentEvents(period);
13429
+ const metrics2 = this.calculateMetrics(recentEvents);
13430
+ const key2 = `${period}_${Date.now()}`;
13431
+ this.metricsBuffer.set(key2, metrics2);
13432
+ console.log(`[Telemetry] Aggregated ${period} metrics:`, {
13433
+ responses: metrics2.totalResponses,
13434
+ avgLatency: Math.round(metrics2.averageLatency),
13435
+ satisfaction: Math.round(metrics2.satisfactionRate * 100) + "%"
13436
+ });
13437
+ }
13438
+ /**
13439
+ * Get recent events by period
13440
+ */
13441
+ getRecentEvents(period) {
13442
+ const now2 = Date.now();
13443
+ const duration = period === "minute" ? 6e4 : period === "hour" ? 36e5 : 864e5;
13444
+ return this.events.filter((e2) => e2.timestamp > now2 - duration);
13445
+ }
13446
+ /**
13447
+ * Get current metrics
13448
+ */
13449
+ getCurrentMetrics() {
13450
+ const keys = Array.from(this.metricsBuffer.keys()).filter((k) => k.startsWith("minute_")).sort();
13451
+ if (keys.length === 0) return null;
13452
+ return this.metricsBuffer.get(keys[keys.length - 1]) || null;
13453
+ }
13454
+ /**
13455
+ * Get historical metrics
13456
+ */
13457
+ getHistoricalMetrics(period, count = 10) {
13458
+ const prefix = `${period}_`;
13459
+ const keys = Array.from(this.metricsBuffer.keys()).filter((k) => k.startsWith(prefix)).sort().slice(-count);
13460
+ return keys.map((k) => this.metricsBuffer.get(k)).filter(Boolean);
13461
+ }
13462
+ /**
13463
+ * Generate session ID
13464
+ */
13465
+ generateSessionId() {
13466
+ return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
13467
+ }
13468
+ /**
13469
+ * Stop collection
13470
+ */
13471
+ stop() {
13472
+ if (this.flushInterval) {
13473
+ clearInterval(this.flushInterval);
13474
+ this.flushInterval = null;
13475
+ }
13476
+ if (this.aggregationInterval) {
13477
+ clearInterval(this.aggregationInterval);
13478
+ this.aggregationInterval = null;
13479
+ }
13480
+ this.flushEvents();
13481
+ console.log("[Telemetry] Collection stopped");
13482
+ }
13483
+ };
13484
+ }
13485
+ });
13486
+
13487
+ // src/services/ai-response/context.ts
13488
+ function buildContextForAI(sessionMemory2, options2 = {}) {
13489
+ const {
13490
+ budgetChars = 8e3,
13491
+ maxMessages = 20,
13492
+ summaryThreshold = 6
13493
+ } = options2;
13494
+ const reversed = [...sessionMemory2].reverse();
13495
+ const recentMessages2 = [];
13496
+ let totalChars = 0;
13497
+ let messageCount = 0;
13498
+ for (const msg2 of reversed) {
13499
+ const content2 = msg2.content || "";
13500
+ const msgLength = content2.length;
13501
+ if (totalChars + msgLength > budgetChars || messageCount >= maxMessages) {
13502
+ break;
13503
+ }
13504
+ recentMessages2.push({
13505
+ role: msg2.role,
13506
+ content: content2,
13507
+ timestamp: msg2.timestamp
13508
+ });
13509
+ totalChars += msgLength;
13510
+ messageCount++;
13511
+ }
13512
+ recentMessages2.reverse();
13513
+ let rollingSummary;
13514
+ if (sessionMemory2.length > summaryThreshold && recentMessages2.length < sessionMemory2.length) {
13515
+ const olderMessages = sessionMemory2.slice(0, sessionMemory2.length - recentMessages2.length);
13516
+ rollingSummary = createRollingSummary(olderMessages, 1200);
13517
+ }
13518
+ return {
13519
+ recentMessages: recentMessages2,
13520
+ rollingSummary,
13521
+ totalChars,
13522
+ messageCount
13523
+ };
13524
+ }
13525
+ function createRollingSummary(messages2, maxChars) {
13526
+ const summaryParts = [];
13527
+ let currentLength = 0;
13528
+ for (const msg2 of messages2) {
13529
+ const role2 = msg2.role === "user" ? "U" : "A";
13530
+ const preview = msg2.content.substring(0, 100).replace(/\n/g, " ");
13531
+ const summary = `${role2}: ${preview}${msg2.content.length > 100 ? "..." : ""}`;
13532
+ if (currentLength + summary.length > maxChars) {
13533
+ break;
13534
+ }
13535
+ summaryParts.push(summary);
13536
+ currentLength += summary.length + 1;
13537
+ }
13538
+ return summaryParts.join("\n");
13539
+ }
13540
+ function extractKeyTopics(context2) {
13541
+ const topics = /* @__PURE__ */ new Set();
13542
+ const allText = context2.recentMessages.map((m2) => m2.content).join(" ").toLowerCase();
13543
+ const languages2 = ["typescript", "javascript", "python", "java", "go", "rust", "react", "vue", "angular"];
13544
+ languages2.forEach((lang) => {
13545
+ if (allText.includes(lang)) topics.add(lang);
13546
+ });
13547
+ const tools = ["next.js", "nextjs", "express", "fastapi", "django", "spring", "docker", "kubernetes"];
13548
+ tools.forEach((tool2) => {
13549
+ if (allText.includes(tool2)) topics.add(tool2);
13550
+ });
13551
+ const concepts = ["api", "database", "authentication", "testing", "deployment", "frontend", "backend"];
13552
+ concepts.forEach((concept) => {
13553
+ if (allText.includes(concept)) topics.add(concept);
13554
+ });
13555
+ return Array.from(topics);
13556
+ }
13557
+ function getContextStats(context2) {
13558
+ return {
13559
+ messageCount: context2.messageCount,
13560
+ totalChars: context2.totalChars,
13561
+ hasSummary: !!context2.rollingSummary,
13562
+ avgMessageLength: context2.totalChars / (context2.messageCount || 1),
13563
+ topics: extractKeyTopics(context2)
13564
+ };
13565
+ }
13566
+ var init_context = __esm({
13567
+ "src/services/ai-response/context.ts"() {
13568
+ }
13569
+ });
13570
+
13571
+ // src/services/ai-response/responders/common.ts
13572
+ function generateFooter(isJapanese, customOptions) {
13573
+ if (customOptions && customOptions.length > 0) {
13574
+ const numbered = customOptions.map((opt, i2) => `${i2 + 1}) ${opt}`).join(" ");
13575
+ return isJapanese ? `
13576
+ ---
13577
+ \u6B21\u306E\u30B9\u30C6\u30C3\u30D7: ${numbered}
13578
+ \u756A\u53F7\u3067\u6307\u793A\u3057\u3066\u304F\u3060\u3055\u3044\u3002` : `
13579
+ ---
13580
+ Next steps: ${numbered}
13581
+ Reply with a number.`;
13582
+ }
13583
+ return isJapanese ? "\n---\n\u6B21\u306B\u9032\u3081\u308B\u9805\u76EE: 1) \u6700\u5C0F\u3067\u52D5\u304B\u3059 2) \u8A2D\u8A08\u3092\u56FA\u3081\u308B 3) \u65E2\u5B58\u30B3\u30FC\u30C9\u306B\u9069\u7528\n\u756A\u53F7\u3067\u6307\u793A\u3057\u3066\u304F\u3060\u3055\u3044\u3002" : "\n---\nNext: 1) Run minimal 2) Lock design 3) Apply to existing\nReply with a number.";
13584
+ }
13585
+ function formatFileBlock(path21, lang, content2) {
13586
+ return `**${path21}**
13587
+ \`\`\`${lang}
13588
+ ${content2}
13589
+ \`\`\``;
13590
+ }
13591
+ function createSectionHeader(title2, level2 = 2) {
13592
+ const prefix = "#".repeat(level2);
13593
+ return `${prefix} ${title2}`;
13594
+ }
13595
+ function formatList(items, ordered = false) {
13596
+ return items.map(
13597
+ (item2, i2) => ordered ? `${i2 + 1}. ${item2}` : `\u2022 ${item2}`
13598
+ ).join("\n");
13599
+ }
13600
+ function truncateText(text2, maxLength) {
13601
+ if (text2.length <= maxLength) return text2;
13602
+ return text2.substring(0, maxLength - 3) + "...";
13603
+ }
13604
+ function cleanUserInput(input3) {
13605
+ return input3.trim().replace(/\s+/g, " ").substring(0, 100);
13606
+ }
13607
+ var init_common = __esm({
13608
+ "src/services/ai-response/responders/common.ts"() {
13609
+ }
13610
+ });
13611
+
13612
+ // src/services/ai-response/responders/code.ts
13613
+ function buildCodeResponse(options2) {
13614
+ const {
13615
+ title: title2,
13616
+ files: files2,
13617
+ runCommands,
13618
+ notes = [],
13619
+ dependencies: dependencies2 = [],
13620
+ envVars = {},
13621
+ isJapanese = false
13622
+ } = options2;
13623
+ const parts2 = [];
13624
+ parts2.push(`### ${title2}`);
13625
+ parts2.push("");
13626
+ files2.forEach((file2) => {
13627
+ parts2.push(formatFileBlock(file2.path, file2.lang, file2.content));
13628
+ parts2.push("");
13629
+ });
13630
+ if (dependencies2.length > 0) {
13631
+ parts2.push(isJapanese ? "**\u5FC5\u8981\u306A\u4F9D\u5B58\u95A2\u4FC2**" : "**Dependencies**");
13632
+ parts2.push("```bash");
13633
+ parts2.push(
13634
+ isJapanese ? `pnpm add ${dependencies2.join(" ")}` : `npm install ${dependencies2.join(" ")}`
13635
+ );
13636
+ parts2.push("```");
13637
+ parts2.push("");
13638
+ }
13639
+ if (Object.keys(envVars).length > 0) {
13640
+ parts2.push(isJapanese ? "**\u74B0\u5883\u5909\u6570 (.env)**" : "**Environment Variables (.env)**");
13641
+ parts2.push("```env");
13642
+ Object.entries(envVars).forEach(([key2, value2]) => {
13643
+ parts2.push(`${key2}=${value2}`);
13644
+ });
13645
+ parts2.push("```");
13646
+ parts2.push("");
13647
+ }
13648
+ parts2.push(isJapanese ? "**\u5B9F\u884C\u624B\u9806**" : "**Run Instructions**");
13649
+ parts2.push(formatList(runCommands, true));
13650
+ parts2.push("");
13651
+ const defaultNotes = isJapanese ? ["\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u305F\u5834\u5408\u306F\u3001\u4F9D\u5B58\u95A2\u4FC2\u304C\u6B63\u3057\u304F\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3055\u308C\u3066\u3044\u308B\u304B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044"] : ["If you encounter errors, ensure all dependencies are properly installed"];
13652
+ const allNotes = [...notes, ...defaultNotes];
13653
+ parts2.push(isJapanese ? "**\u6CE8\u610F\u4E8B\u9805**" : "**Notes**");
13654
+ parts2.push(formatList(allNotes));
13655
+ const footerOptions = isJapanese ? ["\u30A8\u30E9\u30FC\u51E6\u7406\u3092\u8FFD\u52A0", "\u30C6\u30B9\u30C8\u3092\u66F8\u304F", "\u6A5F\u80FD\u3092\u62E1\u5F35"] : ["Add error handling", "Write tests", "Extend features"];
13656
+ parts2.push(generateFooter(isJapanese, footerOptions));
13657
+ return parts2.join("\n");
13658
+ }
13659
+ function generateCLITemplate(isJapanese) {
13660
+ return buildCodeResponse({
13661
+ title: isJapanese ? "TypeScript CLI \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3" : "TypeScript CLI Application",
13662
+ files: [
13663
+ {
13664
+ path: "src/index.ts",
13665
+ lang: "typescript",
13666
+ content: `#!/usr/bin/env node
13667
+ import { Command } from 'commander';
13668
+ import chalk from 'chalk';
13669
+
13670
+ const program = new Command();
13671
+
13672
+ program
13673
+ .name('my-cli')
13674
+ .description('CLI application template')
13675
+ .version('1.0.0');
13676
+
13677
+ program
13678
+ .command('greet <name>')
13679
+ .description('Greet someone')
13680
+ .option('-u, --uppercase', 'Convert to uppercase')
13681
+ .action((name: string, options: { uppercase?: boolean }) => {
13682
+ const greeting = options.uppercase
13683
+ ? \`HELLO \${name.toUpperCase()}!\`
13684
+ : \`Hello \${name}!\`;
13685
+ console.log(chalk.green(greeting));
13686
+ });
13687
+
13688
+ program.parse(process.argv);`
13689
+ },
13690
+ {
13691
+ path: "package.json",
13692
+ lang: "json",
13693
+ content: `{
13694
+ "name": "my-cli",
13695
+ "version": "1.0.0",
13696
+ "type": "module",
13697
+ "bin": {
13698
+ "my-cli": "./dist/index.js"
13699
+ },
13700
+ "scripts": {
13701
+ "build": "tsc",
13702
+ "dev": "tsx src/index.ts",
13703
+ "start": "node dist/index.js"
13704
+ },
13705
+ "dependencies": {
13706
+ "chalk": "^5.3.0",
13707
+ "commander": "^11.1.0"
13708
+ },
13709
+ "devDependencies": {
13710
+ "@types/node": "^20.10.0",
13711
+ "tsx": "^4.6.0",
13712
+ "typescript": "^5.3.0"
13713
+ }
13714
+ }`
13715
+ },
13716
+ {
13717
+ path: "tsconfig.json",
13718
+ lang: "json",
13719
+ content: `{
13720
+ "compilerOptions": {
13721
+ "target": "ES2022",
13722
+ "module": "ES2022",
13723
+ "lib": ["ES2022"],
13724
+ "outDir": "./dist",
13725
+ "rootDir": "./src",
13726
+ "strict": true,
13727
+ "esModuleInterop": true,
13728
+ "skipLibCheck": true,
13729
+ "forceConsistentCasingInFileNames": true,
13730
+ "moduleResolution": "node",
13731
+ "resolveJsonModule": true
13732
+ },
13733
+ "include": ["src/**/*"],
13734
+ "exclude": ["node_modules", "dist"]
13735
+ }`
13736
+ }
13737
+ ],
13738
+ runCommands: isJapanese ? [
13739
+ "pnpm install",
13740
+ "pnpm build",
13741
+ "node dist/index.js greet World",
13742
+ "npm link (\u30B0\u30ED\u30FC\u30D0\u30EB\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u7528)"
13743
+ ] : [
13744
+ "npm install",
13745
+ "npm run build",
13746
+ "node dist/index.js greet World",
13747
+ "npm link (for global installation)"
13748
+ ],
13749
+ dependencies: ["chalk", "commander"],
13750
+ notes: isJapanese ? ["tsx \u3092\u4F7F\u7528\u3057\u3066\u958B\u767A\u4E2D\u306F TypeScript \u3092\u76F4\u63A5\u5B9F\u884C\u3067\u304D\u307E\u3059"] : ["Use tsx to run TypeScript directly during development"],
13751
+ isJapanese
13752
+ });
13753
+ }
13754
+ function generateNextAPITemplate(isJapanese) {
13755
+ return buildCodeResponse({
13756
+ title: isJapanese ? "Next.js API \u30EB\u30FC\u30C8" : "Next.js API Route",
13757
+ files: [
13758
+ {
13759
+ path: "app/api/users/route.ts",
13760
+ lang: "typescript",
13761
+ content: `import { NextRequest, NextResponse } from 'next/server';
13762
+
13763
+ // Sample data
13764
+ const users = [
13765
+ { id: 1, name: 'Alice', email: 'alice@example.com' },
13766
+ { id: 2, name: 'Bob', email: 'bob@example.com' }
13767
+ ];
13768
+
13769
+ export async function GET(request: NextRequest) {
13770
+ try {
13771
+ const searchParams = request.nextUrl.searchParams;
13772
+ const id = searchParams.get('id');
13773
+
13774
+ if (id) {
13775
+ const user = users.find(u => u.id === parseInt(id));
13776
+ if (!user) {
13777
+ return NextResponse.json(
13778
+ { error: 'User not found' },
13779
+ { status: 404 }
13780
+ );
13781
+ }
13782
+ return NextResponse.json(user);
13783
+ }
13784
+
13785
+ return NextResponse.json(users);
13786
+ } catch (error) {
13787
+ return NextResponse.json(
13788
+ { error: 'Internal server error' },
13789
+ { status: 500 }
13790
+ );
13791
+ }
13792
+ }
13793
+
13794
+ export async function POST(request: NextRequest) {
13795
+ try {
13796
+ const body = await request.json();
13797
+ const { name, email } = body;
13798
+
13799
+ if (!name || !email) {
13800
+ return NextResponse.json(
13801
+ { error: 'Name and email are required' },
13802
+ { status: 400 }
13803
+ );
13804
+ }
13805
+
13806
+ const newUser = {
13807
+ id: users.length + 1,
13808
+ name,
13809
+ email
13810
+ };
13811
+
13812
+ users.push(newUser);
13813
+
13814
+ return NextResponse.json(newUser, { status: 201 });
13815
+ } catch (error) {
13816
+ return NextResponse.json(
13817
+ { error: 'Invalid request body' },
13818
+ { status: 400 }
13819
+ );
13820
+ }
13821
+ }`
13822
+ },
13823
+ {
13824
+ path: "app/api/users/[id]/route.ts",
13825
+ lang: "typescript",
13826
+ content: `import { NextRequest, NextResponse } from 'next/server';
13827
+
13828
+ export async function GET(
13829
+ request: NextRequest,
13830
+ { params }: { params: { id: string } }
13831
+ ) {
13832
+ return NextResponse.json({
13833
+ message: \`User \${params.id} details\`
13834
+ });
13835
+ }
13836
+
13837
+ export async function PUT(
13838
+ request: NextRequest,
13839
+ { params }: { params: { id: string } }
13840
+ ) {
13841
+ const body = await request.json();
13842
+ return NextResponse.json({
13843
+ message: \`Updated user \${params.id}\`,
13844
+ data: body
13845
+ });
13846
+ }
13847
+
13848
+ export async function DELETE(
13849
+ request: NextRequest,
13850
+ { params }: { params: { id: string } }
13851
+ ) {
13852
+ return NextResponse.json({
13853
+ message: \`Deleted user \${params.id}\`
13854
+ });
13855
+ }`
13856
+ }
13857
+ ],
13858
+ runCommands: isJapanese ? [
13859
+ "Next.js \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306B\u914D\u7F6E",
13860
+ "pnpm dev \u3067\u30B5\u30FC\u30D0\u30FC\u8D77\u52D5",
13861
+ "curl http://localhost:3000/api/users \u3067\u30C6\u30B9\u30C8"
13862
+ ] : [
13863
+ "Place in Next.js project",
13864
+ "Run server with npm run dev",
13865
+ "Test with curl http://localhost:3000/api/users"
13866
+ ],
13867
+ notes: isJapanese ? [
13868
+ "App Router (Next.js 13+) \u3092\u4F7F\u7528",
13869
+ "\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u63A5\u7D9A\u306F\u5225\u9014\u5B9F\u88C5\u304C\u5FC5\u8981",
13870
+ "Middleware \u3067\u8A8D\u8A3C\u3092\u8FFD\u52A0\u53EF\u80FD"
13871
+ ] : [
13872
+ "Uses App Router (Next.js 13+)",
13873
+ "Database connection needs separate implementation",
13874
+ "Can add authentication via middleware"
13875
+ ],
13876
+ envVars: {
13877
+ "DATABASE_URL": "postgresql://user:pass@localhost/db"
13878
+ },
13879
+ isJapanese
13880
+ });
13881
+ }
13882
+ var init_code = __esm({
13883
+ "src/services/ai-response/responders/code.ts"() {
13884
+ init_common();
13885
+ }
13886
+ });
13887
+
13888
+ // src/services/ai-response/responders/continuation.ts
13889
+ function buildContinuationPrompt(contextPreview, isJapanese, customOptions) {
13890
+ const parts2 = [];
13891
+ parts2.push(isJapanese ? "\u7D9A\u304D\u3067\u3059\u306D\u3002\u76F4\u8FD1\u306E\u6D41\u308C\u3092\u78BA\u8A8D\u3057\u307E\u3057\u305F\u3002" : "I see you want to continue. Here's the recent context.");
13892
+ parts2.push("");
13893
+ if (contextPreview) {
13894
+ parts2.push(isJapanese ? "**\u76F4\u8FD1\u306E\u5185\u5BB9:**" : "**Recent context:**");
13895
+ parts2.push(`> ${truncateText(contextPreview, 300)}`);
13896
+ parts2.push("");
13897
+ }
13898
+ const defaultOptions = isJapanese ? [
13899
+ "\u30A8\u30E9\u30FC\u51E6\u7406\u306E\u8FFD\u52A0\uFF08try/catch\u30FB\u5177\u4F53\u7684\u30E1\u30C3\u30BB\u30FC\u30B8\uFF09",
13900
+ "\u30E2\u30B8\u30E5\u30FC\u30EB\u5206\u5272\uFF08\u95A2\u5FC3\u306E\u5206\u96E2\uFF09",
13901
+ "\u30C6\u30B9\u30C8\u8FFD\u52A0\uFF08\u5358\u4F53\u30C6\u30B9\u30C8\u30FB\u7D71\u5408\u30C6\u30B9\u30C8\uFF09",
13902
+ "\u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u6539\u5584\uFF08\u6700\u9069\u5316\u30FB\u30AD\u30E3\u30C3\u30B7\u30E5\uFF09",
13903
+ "\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u4F5C\u6210\uFF08README\u30FBAPI\u4ED5\u69D8\uFF09"
13904
+ ] : [
13905
+ "Add error handling (try/catch with specific messages)",
13906
+ "Split into modules (separation of concerns)",
13907
+ "Add tests (unit and integration)",
13908
+ "Improve performance (optimization & caching)",
13909
+ "Create documentation (README & API specs)"
13910
+ ];
13911
+ const options2 = customOptions && customOptions.length > 0 ? customOptions : defaultOptions;
13912
+ parts2.push(
13913
+ isJapanese ? "**\u6B21\u306E\u30B9\u30C6\u30C3\u30D7\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044:**" : "**Choose your next step:**"
13914
+ );
13915
+ parts2.push("");
13916
+ options2.forEach((option, i2) => {
13917
+ parts2.push(`${i2 + 1}) ${option}`);
13918
+ });
13919
+ parts2.push("");
13920
+ parts2.push(
13921
+ isJapanese ? "\u{1F4A1} \u63A8\u5968: \u8FF7\u3046\u5834\u5408\u306F 2\u21921\u21923 \u306E\u9806\u304C\u304A\u3059\u3059\u3081\u3067\u3059\u3002" : "\u{1F4A1} Tip: If unsure, try 2\u21921\u21923 in that order."
13922
+ );
13923
+ parts2.push(
13924
+ isJapanese ? "\n\u756A\u53F7\u3067\u6307\u793A\u3057\u3066\u304F\u3060\u3055\u3044\uFF081-5\uFF09\u3002\u8A73\u7D30\u306A\u8AAC\u660E\u3092\u8FFD\u52A0\u3057\u3066\u3082\u69CB\u3044\u307E\u305B\u3093\u3002" : "\nReply with a number (1-5). You can add details to your choice."
13925
+ );
13926
+ return parts2.join("\n");
13927
+ }
13928
+ function generateTopicBasedContinuation(topics, isJapanese) {
13929
+ const options2 = [];
13930
+ if (topics.some((t) => ["react", "vue", "angular", "frontend"].includes(t))) {
13931
+ options2.push(
13932
+ isJapanese ? "\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u306E\u5206\u5272\u3068props\u8A2D\u8A08" : "Component splitting and props design"
13933
+ );
13934
+ options2.push(
13935
+ isJapanese ? "\u72B6\u614B\u7BA1\u7406\u306E\u5B9F\u88C5\uFF08Context/Redux/Zustand\uFF09" : "State management (Context/Redux/Zustand)"
13936
+ );
13937
+ }
13938
+ if (topics.some((t) => ["api", "backend", "express", "fastapi"].includes(t))) {
13939
+ options2.push(
13940
+ isJapanese ? "API\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306E\u8FFD\u52A0" : "Add API endpoints"
13941
+ );
13942
+ options2.push(
13943
+ isJapanese ? "\u8A8D\u8A3C\u30FB\u8A8D\u53EF\u306E\u5B9F\u88C5" : "Implement authentication & authorization"
13944
+ );
13945
+ }
13946
+ if (topics.some((t) => ["database", "sql", "mongodb", "postgres"].includes(t))) {
13947
+ options2.push(
13948
+ isJapanese ? "\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30B9\u30AD\u30FC\u30DE\u306E\u8A2D\u8A08" : "Design database schema"
13949
+ );
13950
+ options2.push(
13951
+ isJapanese ? "\u30DE\u30A4\u30B0\u30EC\u30FC\u30B7\u30E7\u30F3\u3068\u30B7\u30FC\u30C9\u4F5C\u6210" : "Create migrations and seeds"
13952
+ );
13953
+ }
13954
+ if (topics.some((t) => ["test", "testing", "jest", "vitest"].includes(t))) {
13955
+ options2.push(
13956
+ isJapanese ? "\u30E6\u30CB\u30C3\u30C8\u30C6\u30B9\u30C8\u306E\u8FFD\u52A0" : "Add unit tests"
13957
+ );
13958
+ options2.push(
13959
+ isJapanese ? "E2E\u30C6\u30B9\u30C8\u306E\u5B9F\u88C5" : "Implement E2E tests"
13960
+ );
13961
+ }
13962
+ if (options2.length === 0) {
13963
+ options2.push(
13964
+ isJapanese ? "\u30B3\u30FC\u30C9\u306E\u8A73\u7D30\u306A\u5B9F\u88C5" : "Detailed code implementation"
13965
+ );
13966
+ options2.push(
13967
+ isJapanese ? "\u8A2D\u8A08\u30D1\u30BF\u30FC\u30F3\u306E\u9069\u7528" : "Apply design patterns"
13968
+ );
13969
+ }
13970
+ return options2;
13971
+ }
13972
+ function buildSmartContinuation(context2, detectedTopics, isJapanese) {
13973
+ const topicOptions = generateTopicBasedContinuation(detectedTopics, isJapanese);
13974
+ const generalOptions = isJapanese ? ["\u65E2\u5B58\u30B3\u30FC\u30C9\u306E\u30EA\u30D5\u30A1\u30AF\u30BF\u30EA\u30F3\u30B0", "\u65B0\u6A5F\u80FD\u306E\u8FFD\u52A0"] : ["Refactor existing code", "Add new features"];
13975
+ const allOptions = [...topicOptions, ...generalOptions].slice(0, 5);
13976
+ return buildContinuationPrompt(context2, isJapanese, allOptions);
13977
+ }
13978
+ var init_continuation = __esm({
13979
+ "src/services/ai-response/responders/continuation.ts"() {
13980
+ init_common();
13981
+ }
13982
+ });
13983
+
13984
+ // src/services/ai-response/responders/question.ts
13985
+ function buildQuestionResponse(options2) {
13986
+ const { question, isJapanese, topics = [], includeExample = true } = options2;
13987
+ const parts2 = [];
13988
+ const cleanQuestion = cleanUserInput(question);
13989
+ parts2.push(
13990
+ isJapanese ? `\u3054\u8CEA\u554F\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002\u300C${cleanQuestion}\u300D\u306B\u3064\u3044\u3066\u8AAC\u660E\u3057\u307E\u3059\u3002` : `Great question about "${cleanQuestion}". Let me explain.`
13991
+ );
13992
+ parts2.push("");
13993
+ parts2.push(createSectionHeader(
13994
+ isJapanese ? "\u56DE\u7B54\u306E\u69CB\u6210" : "Answer Structure",
13995
+ 3
13996
+ ));
13997
+ parts2.push("");
13998
+ const structure2 = isJapanese ? [
13999
+ "\u80CC\u666F\u3068\u57FA\u672C\u6982\u5FF5",
14000
+ "\u5B9F\u88C5\u65B9\u6CD5\uFF08\u6700\u5C0F\u4F8B\uFF09",
14001
+ "\u30D9\u30B9\u30C8\u30D7\u30E9\u30AF\u30C6\u30A3\u30B9\u3068\u6CE8\u610F\u70B9",
14002
+ "\u5B9F\u969B\u306E\u4F7F\u7528\u4F8B"
14003
+ ] : [
14004
+ "Background & Concepts",
14005
+ "Implementation (minimal example)",
14006
+ "Best practices & pitfalls",
14007
+ "Real-world use cases"
14008
+ ];
14009
+ parts2.push(formatList(structure2, true));
14010
+ parts2.push("");
14011
+ parts2.push(createSectionHeader(
14012
+ isJapanese ? "\u7C21\u6F54\u306A\u56DE\u7B54" : "Quick Answer",
14013
+ 3
14014
+ ));
14015
+ parts2.push("");
14016
+ parts2.push(generateQuickAnswer(question, isJapanese, topics));
14017
+ parts2.push("");
14018
+ if (includeExample && shouldIncludeCode(question)) {
14019
+ parts2.push(createSectionHeader(
14020
+ isJapanese ? "\u30B3\u30FC\u30C9\u4F8B" : "Code Example",
14021
+ 3
14022
+ ));
14023
+ parts2.push("");
14024
+ parts2.push(generateExampleCode(topics));
14025
+ parts2.push("");
14026
+ }
14027
+ parts2.push(createSectionHeader(
14028
+ isJapanese ? "\u8A73\u7D30\u3092\u77E5\u308A\u305F\u3044\u5834\u5408" : "Want to know more?",
14029
+ 3
14030
+ ));
14031
+ parts2.push("");
14032
+ const detailOptions = isJapanese ? [
14033
+ "\u8A73\u7D30\u306A\u5B9F\u88C5\u4F8B\u3092\u898B\u308B",
14034
+ "\u95A2\u9023\u3059\u308B\u6982\u5FF5\u3092\u5B66\u3076",
14035
+ "\u30C8\u30E9\u30D6\u30EB\u30B7\u30E5\u30FC\u30C6\u30A3\u30F3\u30B0",
14036
+ "\u5B9F\u969B\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3078\u306E\u9069\u7528"
14037
+ ] : [
14038
+ "See detailed implementation",
14039
+ "Learn related concepts",
14040
+ "Troubleshooting guide",
14041
+ "Apply to real project"
14042
+ ];
14043
+ parts2.push(formatList(detailOptions, true));
14044
+ parts2.push("");
14045
+ parts2.push(
14046
+ isJapanese ? "\u756A\u53F7\u3092\u9078\u3093\u3067\u8A73\u7D30\u3092\u78BA\u8A8D\u3059\u308B\u304B\u3001\u8FFD\u52A0\u306E\u8CEA\u554F\u3092\u3057\u3066\u304F\u3060\u3055\u3044\u3002" : "Choose a number for details or ask a follow-up question."
14047
+ );
14048
+ return parts2.join("\n");
14049
+ }
14050
+ function generateQuickAnswer(question, isJapanese, topics) {
14051
+ const lowerQuestion = question.toLowerCase();
14052
+ if (lowerQuestion.includes("difference") || lowerQuestion.includes("\u9055\u3044")) {
14053
+ return isJapanese ? "\u4E3B\u306A\u9055\u3044\u306F\u3001\u76EE\u7684\u3068\u4F7F\u7528\u5834\u9762\u306B\u3042\u308A\u307E\u3059\u3002\u305D\u308C\u305E\u308C\u306E\u7279\u5FB4\u3092\u6BD4\u8F03\u3059\u308B\u3068..." : "The main difference lies in their purpose and use cases. Comparing their features...";
14054
+ }
14055
+ if (lowerQuestion.includes("how to") || lowerQuestion.includes("\u65B9\u6CD5")) {
14056
+ return isJapanese ? "\u5B9F\u88C5\u3059\u308B\u306B\u306F\u3001\u4EE5\u4E0B\u306E\u624B\u9806\u306B\u5F93\u3044\u307E\u3059\uFF1A1) \u6E96\u5099\u30012) \u5B9F\u88C5\u30013) \u30C6\u30B9\u30C8" : "To implement this, follow these steps: 1) Setup, 2) Implementation, 3) Testing";
14057
+ }
14058
+ if (lowerQuestion.includes("why") || lowerQuestion.includes("\u306A\u305C")) {
14059
+ return isJapanese ? "\u3053\u308C\u306B\u306F\u6280\u8853\u7684\u306A\u7406\u7531\u3068\u5B9F\u7528\u7684\u306A\u7406\u7531\u304C\u3042\u308A\u307E\u3059\u3002\u4E3B\u306A\u7406\u7531\u306F..." : "There are both technical and practical reasons. The main reasons are...";
14060
+ }
14061
+ if (lowerQuestion.includes("when") || lowerQuestion.includes("\u3044\u3064")) {
14062
+ return isJapanese ? "\u4F7F\u7528\u3059\u308B\u30BF\u30A4\u30DF\u30F3\u30B0\u306F\u3001\u7279\u5B9A\u306E\u6761\u4EF6\u304C\u63C3\u3063\u305F\u6642\u3067\u3059\u3002\u5177\u4F53\u7684\u306B\u306F..." : "Use this when specific conditions are met. Specifically...";
14063
+ }
14064
+ return isJapanese ? `${topics.length > 0 ? topics[0] + "\u306B\u95A2\u3057\u3066\u3001" : ""}\u91CD\u8981\u306A\u30DD\u30A4\u30F3\u30C8\u3092\u307E\u3068\u3081\u308B\u3068...` : `${topics.length > 0 ? "Regarding " + topics[0] + ", " : ""}The key points are...`;
14065
+ }
14066
+ function shouldIncludeCode(question) {
14067
+ const codeIndicators = [
14068
+ "implement",
14069
+ "code",
14070
+ "example",
14071
+ "how to",
14072
+ "\u5B9F\u88C5",
14073
+ "\u30B3\u30FC\u30C9",
14074
+ "\u4F8B",
14075
+ "\u65B9\u6CD5",
14076
+ "\u30B5\u30F3\u30D7\u30EB"
14077
+ ];
14078
+ const lower = question.toLowerCase();
14079
+ return codeIndicators.some((indicator) => lower.includes(indicator));
14080
+ }
14081
+ function generateExampleCode(topics) {
14082
+ if (topics.includes("react")) {
14083
+ return `\`\`\`tsx
14084
+ const MyComponent = ({ title }: { title: string }) => {
14085
+ const [count, setCount] = useState(0);
14086
+
14087
+ return (
14088
+ <div>
14089
+ <h1>{title}</h1>
14090
+ <button onClick={() => setCount(c => c + 1)}>
14091
+ Count: {count}
14092
+ </button>
14093
+ </div>
14094
+ );
14095
+ };
14096
+ \`\`\``;
14097
+ }
14098
+ if (topics.includes("api")) {
14099
+ return `\`\`\`typescript
14100
+ app.get('/api/users/:id', async (req, res) => {
14101
+ try {
14102
+ const user = await getUserById(req.params.id);
14103
+ res.json(user);
14104
+ } catch (error) {
14105
+ res.status(404).json({ error: 'User not found' });
14106
+ }
14107
+ });
14108
+ \`\`\``;
14109
+ }
14110
+ return `\`\`\`typescript
14111
+ // Example implementation
14112
+ function solution(input: string): string {
14113
+ // Process input
14114
+ const processed = input.trim().toLowerCase();
14115
+
14116
+ // Apply logic
14117
+ const result = processData(processed);
14118
+
14119
+ // Return result
14120
+ return result;
14121
+ }
14122
+ \`\`\``;
14123
+ }
14124
+ function buildComprehensiveAnswer(question, detectedTopics, isJapanese) {
14125
+ return buildQuestionResponse({
14126
+ question,
14127
+ isJapanese,
14128
+ topics: detectedTopics,
14129
+ includeExample: true
14130
+ });
14131
+ }
14132
+ var init_question = __esm({
14133
+ "src/services/ai-response/responders/question.ts"() {
14134
+ init_common();
14135
+ }
14136
+ });
14137
+
14138
+ // src/services/ai-response/guards/safety.ts
14139
+ function checkInputSafety(input3, config2 = {}) {
14140
+ const {
14141
+ enablePIICheck = true,
14142
+ enablePromptInjectionCheck = true
14143
+ } = config2;
14144
+ if (enablePIICheck && containsPII(input3)) {
14145
+ return {
14146
+ safe: false,
14147
+ reason: "Input contains potential personal information",
14148
+ suggestion: "Please remove sensitive information before proceeding"
14149
+ };
14150
+ }
14151
+ if (enablePromptInjectionCheck && containsInjection(input3)) {
14152
+ return {
14153
+ safe: false,
14154
+ reason: "Input contains potential prompt injection",
14155
+ suggestion: "Please rephrase your request without system instructions"
14156
+ };
14157
+ }
14158
+ const harmful = detectHarmfulContent(input3);
14159
+ if (harmful.length > 0) {
14160
+ return {
14161
+ safe: true,
14162
+ // Allow but warn
14163
+ reason: `Note: Input mentions sensitive topics: ${harmful.join(", ")}`,
14164
+ suggestion: "Ensure you're not exposing sensitive data"
14165
+ };
14166
+ }
14167
+ return { safe: true };
14168
+ }
14169
+ function checkOutputSafety(output2, config2 = {}) {
14170
+ const {
14171
+ maxOutputChars = 5e4,
14172
+ // ~50KB
14173
+ maxCodeBlocks = 10
14174
+ } = config2;
14175
+ if (output2.length > maxOutputChars) {
14176
+ return {
14177
+ safe: false,
14178
+ reason: `Output too large (${output2.length} chars > ${maxOutputChars})`,
14179
+ suggestion: "Output has been truncated for safety"
14180
+ };
14181
+ }
14182
+ const codeBlockCount = (output2.match(/```/g) || []).length / 2;
14183
+ if (codeBlockCount > maxCodeBlocks) {
14184
+ return {
14185
+ safe: false,
14186
+ reason: `Too many code blocks (${codeBlockCount} > ${maxCodeBlocks})`,
14187
+ suggestion: "Consider splitting into multiple responses"
14188
+ };
14189
+ }
14190
+ return { safe: true };
14191
+ }
14192
+ function containsPII(input3) {
14193
+ return PII_PATTERNS.some((pattern2) => pattern2.test(input3));
14194
+ }
14195
+ function containsInjection(input3) {
14196
+ return INJECTION_PATTERNS.some((pattern2) => pattern2.test(input3));
14197
+ }
14198
+ function detectHarmfulContent(input3) {
14199
+ const lower = input3.toLowerCase();
14200
+ return HARMFUL_KEYWORDS.filter((keyword) => lower.includes(keyword.toLowerCase()));
14201
+ }
14202
+ function sanitizeOutput(output2, maxChars = 5e4) {
14203
+ if (output2.length > maxChars) {
14204
+ return output2.substring(0, maxChars) + "\n\n... [Output truncated for safety]";
14205
+ }
14206
+ let sanitized = output2;
14207
+ PII_PATTERNS.forEach((pattern2) => {
14208
+ sanitized = sanitized.replace(pattern2, "[REDACTED]");
14209
+ });
14210
+ return sanitized;
14211
+ }
14212
+ function isExplicitContentAllowed(input3, explicitKeyword) {
14213
+ const lower = input3.toLowerCase();
14214
+ return lower.includes(explicitKeyword.toLowerCase());
14215
+ }
14216
+ function generateRejectionMessage(reason, isJapanese) {
14217
+ const baseMessage = isJapanese ? `\u7533\u3057\u8A33\u3054\u3056\u3044\u307E\u305B\u3093\u3002\u5B89\u5168\u4E0A\u306E\u7406\u7531\u306B\u3088\u308A\u3001\u3053\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u306F\u51E6\u7406\u3067\u304D\u307E\u305B\u3093\u3002` : `I apologize, but I cannot process this request for safety reasons.`;
14218
+ const suggestions2 = isJapanese ? [
14219
+ "\u500B\u4EBA\u60C5\u5831\u3092\u9664\u5916\u3057\u3066\u304F\u3060\u3055\u3044",
14220
+ "\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u8A00\u3044\u63DB\u3048\u3066\u304F\u3060\u3055\u3044",
14221
+ "\u5C0F\u3055\u306A\u90E8\u5206\u306B\u5206\u5272\u3057\u3066\u304F\u3060\u3055\u3044"
14222
+ ] : [
14223
+ "Remove personal information",
14224
+ "Rephrase your request",
14225
+ "Break into smaller parts"
14226
+ ];
14227
+ return `${baseMessage}
14228
+
14229
+ **${isJapanese ? "\u7406\u7531" : "Reason"}:** ${reason}
14230
+
14231
+ **${isJapanese ? "\u63D0\u6848" : "Suggestions"}:**
14232
+ ${suggestions2.map((s2, i2) => `${i2 + 1}. ${s2}`).join("\n")}`;
14233
+ }
14234
+ function logSafetyEvent(event) {
14235
+ console.log("[Safety Guard]", {
14236
+ ...event,
14237
+ timestamp: event.timestamp || Date.now()
14238
+ });
14239
+ }
14240
+ var PII_PATTERNS, HARMFUL_KEYWORDS, INJECTION_PATTERNS;
14241
+ var init_safety = __esm({
14242
+ "src/services/ai-response/guards/safety.ts"() {
14243
+ PII_PATTERNS = [
14244
+ /\b\d{3}-\d{2}-\d{4}\b/,
14245
+ // SSN
14246
+ /\b\d{16}\b/,
14247
+ // Credit card
14248
+ /\b[A-Z]{2}\d{6}\b/,
14249
+ // Passport
14250
+ /\b\d{3}-?\d{3}-?\d{4}\b/
14251
+ // Phone
14252
+ ];
14253
+ HARMFUL_KEYWORDS = [
14254
+ "password",
14255
+ "secret",
14256
+ "token",
14257
+ "api_key",
14258
+ "private_key",
14259
+ "\u30D1\u30B9\u30EF\u30FC\u30C9",
14260
+ "\u30B7\u30FC\u30AF\u30EC\u30C3\u30C8",
14261
+ "\u30C8\u30FC\u30AF\u30F3",
14262
+ "\u79D8\u5BC6\u9375"
14263
+ ];
14264
+ INJECTION_PATTERNS = [
14265
+ /ignore.*previous.*instructions?/i,
14266
+ /disregard.*above/i,
14267
+ /forget.*everything/i,
14268
+ /system.*prompt/i,
14269
+ /you.*are.*now/i,
14270
+ /前の.*指示.*無視/,
14271
+ /システム.*プロンプト/
14272
+ ];
14273
+ }
14274
+ });
14275
+
11760
14276
  // src/services/ai-response.service.ts
11761
14277
  var AIResponseService;
11762
14278
  var init_ai_response_service = __esm({
@@ -11764,216 +14280,345 @@ var init_ai_response_service = __esm({
11764
14280
  init_chat_context_fixed_service();
11765
14281
  init_conversation_persistence();
11766
14282
  init_ai_response_tetris_template();
14283
+ init_intent();
14284
+ init_provider_factory();
14285
+ init_feature_flags();
14286
+ init_telemetry_collector();
14287
+ init_context();
14288
+ init_code();
14289
+ init_continuation();
14290
+ init_question();
14291
+ init_safety();
11767
14292
  AIResponseService = class {
11768
14293
  chatContext;
11769
- conversationPersistence;
14294
+ _conversationPersistence;
14295
+ providerFactory;
14296
+ telemetry;
14297
+ initialized = false;
11770
14298
  constructor() {
11771
14299
  this.chatContext = ChatContextService.getInstance();
11772
- this.conversationPersistence = new ConversationPersistence();
14300
+ this._conversationPersistence = new ConversationPersistence();
14301
+ this.providerFactory = AIProviderFactory.getInstance();
14302
+ this.telemetry = TelemetryCollector.getInstance();
14303
+ this.initializeProviders().catch(console.error);
14304
+ }
14305
+ /**
14306
+ * Initialize AI providers based on configuration
14307
+ */
14308
+ async initializeProviders() {
14309
+ if (this.initialized) return;
14310
+ try {
14311
+ await this.providerFactory.initializeFromEnvironment();
14312
+ this.initialized = true;
14313
+ console.log("[AI Response Service] Providers initialized");
14314
+ } catch (error2) {
14315
+ console.error("[AI Response Service] Provider initialization failed:", error2);
14316
+ }
11773
14317
  }
11774
14318
  /**
11775
- * Generate intelligent AI response using actual providers
11776
- * Replaces the hard-coded template system
14319
+ * Generate intelligent AI response with multi-language support and safety guards
14320
+ * v3.0 - Complete rewrite with modular architecture
11777
14321
  */
11778
14322
  async generateResponse(request2, options2 = {}) {
14323
+ const startTime = Date.now();
11779
14324
  try {
14325
+ const inputSafety = checkInputSafety(request2.userInput);
14326
+ if (!inputSafety.safe) {
14327
+ logSafetyEvent({ type: "input_check", safe: false, reason: inputSafety.reason });
14328
+ const lang = detectLanguage(request2.userInput);
14329
+ return generateRejectionMessage(inputSafety.reason || "Safety check failed", lang === "ja");
14330
+ }
11780
14331
  await this.chatContext.addMessage({
11781
14332
  role: "user",
11782
14333
  content: request2.userInput
11783
14334
  });
11784
- const context2 = this.buildContextForAI(request2);
11785
- const aiResponse = await this.callAIProvider(context2, options2);
14335
+ const context2 = buildContextForAI(
14336
+ request2.sessionMemory,
14337
+ {
14338
+ budgetChars: options2.contextLength ? options2.contextLength * 4 : 8e3,
14339
+ maxMessages: 20
14340
+ }
14341
+ );
14342
+ const language2 = detectLanguage(request2.userInput);
14343
+ const recentText = context2.recentMessages.map((m2) => m2.content).join(" ");
14344
+ const intent2 = analyzeIntent(request2.userInput, recentText);
14345
+ if (featureFlags.isEnabled("enableTelemetry")) {
14346
+ this.telemetry.trackIntent({
14347
+ type: intent2.type,
14348
+ confidence: intent2.confidence,
14349
+ language: language2,
14350
+ timestamp: Date.now()
14351
+ });
14352
+ }
14353
+ let aiResponse;
14354
+ const config2 = featureFlags.getAIResponseConfig();
14355
+ if (config2.useRealProviders && intent2.type !== "TETRIS_REQUEST") {
14356
+ aiResponse = await this.generateWithProvider(
14357
+ request2.userInput,
14358
+ context2,
14359
+ language2,
14360
+ options2
14361
+ );
14362
+ } else {
14363
+ aiResponse = await this.routeByIntent(
14364
+ intent2,
14365
+ request2.userInput,
14366
+ context2,
14367
+ { language: language2, options: options2 }
14368
+ );
14369
+ }
14370
+ const outputSafety = checkOutputSafety(aiResponse);
14371
+ const finalResponse = outputSafety.safe ? aiResponse : sanitizeOutput(aiResponse, 5e4);
11786
14372
  await this.chatContext.addMessage({
11787
14373
  role: "assistant",
11788
- content: aiResponse
14374
+ content: finalResponse
11789
14375
  });
11790
- return aiResponse;
14376
+ const latency = Date.now() - startTime;
14377
+ if (featureFlags.isEnabled("enableTelemetry")) {
14378
+ this.telemetry.trackResponse({
14379
+ provider: config2.useRealProviders ? config2.providerType : "template",
14380
+ model: "unknown",
14381
+ // Would need to get from provider
14382
+ latencyMs: latency,
14383
+ success: true,
14384
+ fallback: !config2.useRealProviders,
14385
+ timestamp: Date.now()
14386
+ });
14387
+ }
14388
+ return finalResponse;
11791
14389
  } catch (error2) {
11792
14390
  console.error("AI Response generation failed:", error2);
14391
+ logSafetyEvent({ type: "rejection", safe: false, reason: "Generation failed" });
14392
+ if (featureFlags.isEnabled("enableTelemetry")) {
14393
+ this.telemetry.trackError(error2, {
14394
+ userInput: request2.userInput,
14395
+ provider: "unknown"
14396
+ });
14397
+ }
11793
14398
  return this.generateFallbackResponse(request2.userInput);
11794
14399
  }
11795
14400
  }
11796
14401
  /**
11797
- * Build context for AI provider
11798
- */
11799
- buildContextForAI(request2) {
11800
- const recentContext = request2.sessionMemory.slice(-5);
11801
- return {
11802
- messages: recentContext.map((msg2) => ({
11803
- role: msg2.role,
11804
- content: msg2.content
11805
- })),
11806
- currentInput: request2.userInput,
11807
- contextStats: this.chatContext.getStats()
11808
- };
11809
- }
11810
- /**
11811
- * Call actual AI provider with intelligent intent recognition
14402
+ * Route request to appropriate responder based on intent
14403
+ * v3.0 - New routing logic with language awareness
11812
14404
  */
11813
- async callAIProvider(context2, _options) {
11814
- const userInput2 = context2.currentInput.toLowerCase();
11815
- const hasContext = context2.messages.length > 0;
11816
- const intent2 = this.analyzeIntent(userInput2, context2);
14405
+ async routeByIntent(intent2, userInput2, context2, config2) {
14406
+ const { language: language2 } = config2;
14407
+ const isJapanese = language2 === "ja";
14408
+ const topics = extractKeyTopics(context2);
11817
14409
  switch (intent2.type) {
11818
14410
  case "TETRIS_REQUEST":
11819
- return this.generateTetrisGame(userInput2);
14411
+ if (isExplicitContentAllowed(userInput2, "tetris")) {
14412
+ return generateTetrisGameTemplate(userInput2);
14413
+ }
14414
+ return this.generateDefaultResponse(userInput2);
11820
14415
  case "CODE_REQUEST":
11821
- return this.generateCodeResponse(userInput2, context2);
14416
+ if (userInput2.toLowerCase().includes("cli")) {
14417
+ return generateCLITemplate(isJapanese);
14418
+ }
14419
+ if (userInput2.toLowerCase().includes("api") || userInput2.toLowerCase().includes("next")) {
14420
+ return generateNextAPITemplate(isJapanese);
14421
+ }
14422
+ return buildCodeResponse({
14423
+ title: isJapanese ? "\u30B3\u30FC\u30C9\u5B9F\u88C5\u4F8B" : "Code Implementation",
14424
+ files: [{
14425
+ path: "example.ts",
14426
+ lang: "typescript",
14427
+ content: `// Your implementation here
14428
+ console.log('Hello World');`
14429
+ }],
14430
+ runCommands: isJapanese ? ["\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210", "node example.js \u3067\u5B9F\u884C"] : ["Create the file", "Run with node example.js"],
14431
+ isJapanese
14432
+ });
11822
14433
  case "QUESTION":
11823
- return this.generateQuestionResponse(userInput2, context2);
14434
+ return buildComprehensiveAnswer(userInput2, topics, isJapanese);
11824
14435
  case "CONTINUATION":
11825
- return this.generateContinuationResponse(userInput2, context2);
14436
+ const contextPreview = context2.recentMessages.slice(-3).map((m2) => m2.content).join(" ");
14437
+ return buildSmartContinuation(contextPreview, topics, isJapanese);
14438
+ case "SUMMARIZE":
14439
+ return this.generateSummaryResponse(context2, isJapanese);
14440
+ case "REFACTOR":
14441
+ return this.generateRefactorResponse(userInput2, isJapanese);
11826
14442
  default:
11827
- if (hasContext) {
11828
- return this.generateContextualResponse(userInput2, context2);
11829
- }
11830
- return this.generateDefaultResponse(userInput2);
11831
- }
11832
- }
11833
- /**
11834
- * Enhanced intent analysis with context awareness
11835
- */
11836
- analyzeIntent(userInput2, context2) {
11837
- const messages2 = context2.messages || [];
11838
- const recentMessages2 = messages2.slice(-3);
11839
- const contextString = recentMessages2.map((m2) => m2.content).join(" ").toLowerCase();
11840
- if (userInput2.includes("tetris")) {
11841
- return {
11842
- type: "TETRIS_REQUEST",
11843
- confidence: 0.9,
11844
- context: "User wants Tetris game code"
11845
- };
11846
- }
11847
- if (this.isCodeRequest(userInput2)) {
11848
- return {
11849
- type: "CODE_REQUEST",
11850
- confidence: 0.8,
11851
- context: "User wants code implementation"
11852
- };
14443
+ return this.generateSmartDefault(userInput2, topics, isJapanese);
11853
14444
  }
11854
- if (contextString.length > 0 && (userInput2.includes("whole code") || userInput2.includes("complete") || userInput2.includes("start") || userInput2.includes("give me"))) {
11855
- return {
11856
- type: "CONTINUATION",
11857
- confidence: 0.7,
11858
- context: "User continuing previous conversation"
11859
- };
11860
- }
11861
- if (this.isQuestionRequest(userInput2)) {
11862
- return {
11863
- type: "QUESTION",
11864
- confidence: 0.6,
11865
- context: "User asking a question"
11866
- };
11867
- }
11868
- return {
11869
- type: "GENERAL",
11870
- confidence: 0.3,
11871
- context: "General conversation"
11872
- };
11873
14445
  }
11874
14446
  /**
11875
- * Generate continuation response based on context
14447
+ * Generate summary response
11876
14448
  */
11877
- generateContinuationResponse(_input, context2) {
11878
- const messages2 = context2.messages || [];
11879
- const recentMessages2 = messages2.slice(-3);
11880
- const contextString = recentMessages2.map((m2) => m2.content).join(" ");
11881
- return `Got it \u2014 you'd like to continue from our recent context.
14449
+ generateSummaryResponse(context2, isJapanese) {
14450
+ const stats2 = getContextStats(context2);
14451
+ const topics = stats2.topics.join(", ") || (isJapanese ? "\u4E00\u822C\u7684\u306A\u4F1A\u8A71" : "general conversation");
14452
+ return isJapanese ? `\u76F4\u8FD1\u306E\u4F1A\u8A71\u3092\u8981\u7D04\u3057\u307E\u3059\uFF1A
11882
14453
 
11883
- Recent context (last few messages):
11884
- ${contextString.substring(0, 200)}${contextString.length > 200 ? "..." : ""}
14454
+ \u{1F4CA} **\u7D71\u8A08\u60C5\u5831**
14455
+ \u2022 \u30E1\u30C3\u30BB\u30FC\u30B8\u6570: ${stats2.messageCount}
14456
+ \u2022 \u5408\u8A08\u6587\u5B57\u6570: ${stats2.totalChars}
14457
+ \u2022 \u30C8\u30D4\u30C3\u30AF: ${topics}
11885
14458
 
11886
- Please tell me the **exact next step** you want (e.g., "add error handling", "extract function", "write tests", "explain the trade-offs").`;
11887
- }
11888
- /**
11889
- * Detect if user is asking for code/implementation
11890
- */
11891
- isCodeRequest(input3) {
11892
- const codeKeywords = ["implement", "create", "build", "code", "function", "class", "html", "css", "javascript", "python", "typescript"];
11893
- return codeKeywords.some((keyword) => input3.includes(keyword));
11894
- }
11895
- /**
11896
- * Detect if user is asking a question
11897
- */
11898
- isQuestionRequest(input3) {
11899
- const questionWords = ["what", "how", "why", "when", "where", "which", "who"];
11900
- return questionWords.some((word) => input3.startsWith(word)) || input3.includes("?");
11901
- }
11902
- /**
11903
- * Generate code-focused response
11904
- */
11905
- generateCodeResponse(input3, _context) {
11906
- if (input3.includes("tetris") && (input3.includes("html") || input3.includes("index"))) {
11907
- return this.generateTetrisGame(input3);
11908
- }
11909
- return `I understand you want to implement something with code. Let me help you build it step by step.
14459
+ \u{1F4DD} **\u8981\u7D04**
14460
+ ${context2.rollingSummary || "\u8981\u7D04\u3059\u308B\u5185\u5BB9\u304C\u4E0D\u8DB3\u3057\u3066\u3044\u307E\u3059\u3002"}
11910
14461
 
11911
- Based on your request, I'll provide:
11912
- \u2022 Clean, well-commented code
11913
- \u2022 Best practices implementation
11914
- \u2022 Error handling and edge cases
11915
- \u2022 Testing suggestions
14462
+ \u6B21\u306E\u30B9\u30C6\u30C3\u30D7\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF1A
14463
+ 1) \u8A73\u7D30\u306A\u8981\u7D04\u3092\u898B\u308B
14464
+ 2) \u7279\u5B9A\u306E\u30C8\u30D4\u30C3\u30AF\u306B\u7D5E\u308B
14465
+ 3) \u65B0\u3057\u3044\u8CEA\u554F\u3092\u3059\u308B` : `Here's a summary of our recent conversation:
11916
14466
 
11917
- What specific functionality would you like me to focus on first?`;
11918
- }
11919
- /**
11920
- * Generate complete Tetris game code
11921
- */
11922
- generateTetrisGame(input3) {
11923
- return generateTetrisGameTemplate(input3);
14467
+ \u{1F4CA} **Statistics**
14468
+ \u2022 Messages: ${stats2.messageCount}
14469
+ \u2022 Total chars: ${stats2.totalChars}
14470
+ \u2022 Topics: ${topics}
14471
+
14472
+ \u{1F4DD} **Summary**
14473
+ ${context2.rollingSummary || "Not enough content to summarize."}
14474
+
14475
+ Choose your next step:
14476
+ 1) See detailed summary
14477
+ 2) Focus on specific topic
14478
+ 3) Ask a new question`;
11924
14479
  }
11925
14480
  /**
11926
- * Generate question-focused response
14481
+ * Generate refactoring suggestions
11927
14482
  */
11928
- generateQuestionResponse(input3, _context) {
11929
- return `That's a great question! Let me provide you with a comprehensive answer.
14483
+ generateRefactorResponse(input3, isJapanese) {
14484
+ return isJapanese ? `\u30EA\u30D5\u30A1\u30AF\u30BF\u30EA\u30F3\u30B0\u306E\u3054\u8981\u671B\u3067\u3059\u306D\u3002\u300C${input3.substring(0, 50)}\u300D\u3092\u6539\u5584\u3057\u307E\u3059\u3002
11930
14485
 
11931
- Based on your question about "${input3.substring(0, 50)}...", I'll explain:
14486
+ **\u6539\u5584\u30DD\u30A4\u30F3\u30C8**
14487
+ 1) \u53EF\u8AAD\u6027\u306E\u5411\u4E0A\uFF08\u5909\u6570\u540D\u30FB\u95A2\u6570\u540D\u306E\u6539\u5584\uFF09
14488
+ 2) \u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u306E\u6700\u9069\u5316
14489
+ 3) \u91CD\u8907\u30B3\u30FC\u30C9\u306E\u524A\u9664
14490
+ 4) \u30C7\u30B6\u30A4\u30F3\u30D1\u30BF\u30FC\u30F3\u306E\u9069\u7528
11932
14491
 
11933
- \u2022 The technical background and concepts
11934
- \u2022 Practical implementation details
11935
- \u2022 Best practices and common pitfalls
11936
- \u2022 Real-world examples and use cases
14492
+ \u3069\u306E\u89B3\u70B9\u304B\u3089\u59CB\u3081\u307E\u3059\u304B\uFF1F\uFF081-4\u3067\u9078\u629E\uFF09` : `I'll help you refactor "${input3.substring(0, 50)}".
11937
14493
 
11938
- Would you like me to focus on any particular aspect of this topic?`;
14494
+ **Improvement areas**
14495
+ 1) Readability (better naming)
14496
+ 2) Performance optimization
14497
+ 3) Remove duplication
14498
+ 4) Apply design patterns
14499
+
14500
+ Which aspect should we start with? (Choose 1-4)`;
11939
14501
  }
11940
14502
  /**
11941
- * Generate contextual response based on conversation history
14503
+ * Generate smart default response with choices
11942
14504
  */
11943
- generateContextualResponse(input3, context2) {
11944
- const previousTopics = context2.messages.filter((msg2) => msg2.role === "user").map((msg2) => msg2.content.substring(0, 50)).join(", ");
11945
- return `I see we've been discussing: ${previousTopics}
14505
+ generateSmartDefault(input3, topics, isJapanese) {
14506
+ const cleanInput = input3.substring(0, 100);
14507
+ const options2 = isJapanese ? [
14508
+ "\u4ECA\u3059\u3050\u52D5\u304F\u6700\u5C0F\u30B3\u30FC\u30C9",
14509
+ "\u8A2D\u8A08\u65B9\u91DD\u3068\u30C8\u30EC\u30FC\u30C9\u30AA\u30D5",
14510
+ "\u65E2\u5B58\u30B3\u30FC\u30C9\u306E\u6539\u5584\u63D0\u6848",
14511
+ "\u8A73\u7D30\u306A\u8AAC\u660E\u3092\u805E\u304F"
14512
+ ] : [
14513
+ "Minimal working code",
14514
+ "Design & trade-offs",
14515
+ "Improve existing code",
14516
+ "Detailed explanation"
14517
+ ];
14518
+ const topicNote = topics.length > 0 ? isJapanese ? `
14519
+ \u691C\u51FA\u3055\u308C\u305F\u30C8\u30D4\u30C3\u30AF: ${topics.join(", ")}` : `
14520
+ Detected topics: ${topics.join(", ")}` : "";
14521
+ return isJapanese ? `\u3054\u4F9D\u983C\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002\u300C${cleanInput}\u300D\u306B\u3064\u3044\u3066\u5BFE\u5FDC\u3057\u307E\u3059\u3002${topicNote}
11946
14522
 
11947
- Regarding your latest message: "${input3}"
14523
+ \u6700\u77ED\u3067\u76EE\u7684\u3092\u9054\u6210\u3059\u308B\u305F\u3081\u3001\u4EE5\u4E0B\u304B\u3089\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF1A
14524
+ ${options2.map((opt, i2) => `${i2 + 1}) ${opt}`).join("\n")}
11948
14525
 
11949
- Let me build on our previous conversation and provide a detailed response that addresses your specific needs. I'll make sure to connect this to what we've already covered.
14526
+ \u756A\u53F7\u3067\u6307\u793A\u3057\u3066\u304F\u3060\u3055\u3044\uFF081-4\uFF09\u3002` : `Thanks for your request: "${cleanInput}"${topicNote}
11950
14527
 
11951
- What specific aspect would you like me to elaborate on?`;
14528
+ Choose your fastest path to success:
14529
+ ${options2.map((opt, i2) => `${i2 + 1}) ${opt}`).join("\n")}
14530
+
14531
+ Reply with a number (1-4).`;
14532
+ }
14533
+ /**
14534
+ * Generate response using real AI provider
14535
+ */
14536
+ async generateWithProvider(userInput2, context2, language2, options2) {
14537
+ try {
14538
+ const provider2 = await this.providerFactory.getActiveProvider();
14539
+ const messages2 = [];
14540
+ messages2.push({
14541
+ role: "system",
14542
+ content: language2 === "ja" ? "\u3042\u306A\u305F\u306F\u89AA\u5207\u3067\u77E5\u8B58\u8C4A\u5BCC\u306A\u30A2\u30B7\u30B9\u30BF\u30F3\u30C8\u3067\u3059\u3002\u65E5\u672C\u8A9E\u3067\u4E01\u5BE7\u306B\u56DE\u7B54\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30B3\u30FC\u30C9\u3092\u63D0\u4F9B\u3059\u308B\u5834\u5408\u306F\u3001\u5B9F\u884C\u624B\u9806\u3082\u542B\u3081\u3066\u304F\u3060\u3055\u3044\u3002" : "You are a helpful and knowledgeable assistant. Provide clear, actionable responses. When providing code, include execution instructions."
14543
+ });
14544
+ if (context2.rollingSummary) {
14545
+ messages2.push({
14546
+ role: "system",
14547
+ content: `Previous context summary: ${context2.rollingSummary}`
14548
+ });
14549
+ }
14550
+ context2.recentMessages.forEach((msg2) => {
14551
+ messages2.push({
14552
+ role: msg2.role,
14553
+ content: msg2.content
14554
+ });
14555
+ });
14556
+ const lastMessage2 = context2.recentMessages[context2.recentMessages.length - 1];
14557
+ if (!lastMessage2 || lastMessage2.content !== userInput2) {
14558
+ messages2.push({
14559
+ role: "user",
14560
+ content: userInput2
14561
+ });
14562
+ }
14563
+ const response2 = await provider2.generateCompletion({
14564
+ messages: messages2,
14565
+ temperature: options2.temperature,
14566
+ maxTokens: options2.contextLength,
14567
+ streaming: options2.streaming && featureFlags.isEnabled("enableStreaming")
14568
+ });
14569
+ const footer = language2 === "ja" ? "\n\n\u6B21\u306E\u30B9\u30C6\u30C3\u30D7\u3092\u304A\u9078\u3073\u304F\u3060\u3055\u3044\uFF1A\n1) \u8A73\u7D30\u3092\u898B\u308B\n2) \u5B9F\u88C5\u3092\u958B\u59CB\n3) \u5225\u306E\u8CEA\u554F" : "\n\nChoose next step:\n1) See details\n2) Start implementation\n3) Different question";
14570
+ return response2.content + footer;
14571
+ } catch (error2) {
14572
+ console.error("[AI Response] Provider generation failed:", error2);
14573
+ return this.routeByIntent(
14574
+ analyzeIntent(userInput2, ""),
14575
+ userInput2,
14576
+ context2,
14577
+ { language: language2, options: options2 }
14578
+ );
14579
+ }
11952
14580
  }
11953
14581
  /**
11954
- * Generate default intelligent response
14582
+ * Generate default response (kept for compatibility)
11955
14583
  */
11956
14584
  generateDefaultResponse(input3) {
11957
- return `Thank you for your message: "${input3}"
14585
+ const lang = detectLanguage(input3);
14586
+ const isJapanese = lang === "ja";
14587
+ return isJapanese ? `\u300C${input3.substring(0, 50)}\u300D\u306B\u3064\u3044\u3066\u5BFE\u5FDC\u3044\u305F\u3057\u307E\u3059\u3002
11958
14588
 
11959
- I'm ready to help you with:
11960
- \u2022 Technical implementation and coding
11961
- \u2022 Problem-solving and debugging
11962
- \u2022 Architecture and design decisions
11963
- \u2022 Best practices and optimization
14589
+ \u4EE5\u4E0B\u304B\u3089\u304A\u9078\u3073\u304F\u3060\u3055\u3044\uFF1A
14590
+ 1) \u5B9F\u88C5\u65B9\u6CD5\u3092\u898B\u308B
14591
+ 2) \u6982\u5FF5\u3092\u7406\u89E3\u3059\u308B
14592
+ 3) \u554F\u984C\u3092\u89E3\u6C7A\u3059\u308B
11964
14593
 
11965
- How can I assist you with this request?`;
14594
+ \u756A\u53F7\u3067\u304A\u7B54\u3048\u304F\u3060\u3055\u3044\u3002` : `I'll help you with: "${input3.substring(0, 50)}"
14595
+
14596
+ Choose an option:
14597
+ 1) See implementation
14598
+ 2) Understand concepts
14599
+ 3) Solve problems
14600
+
14601
+ Reply with a number.`;
11966
14602
  }
11967
14603
  /**
11968
- * Fallback response for errors
14604
+ * Fallback response for errors with language detection
11969
14605
  */
11970
14606
  generateFallbackResponse(input3) {
11971
- return `I apologize, but I encountered an issue processing your request: "${input3}"
14607
+ const lang = detectLanguage(input3);
14608
+ const isJapanese = lang === "ja";
14609
+ return isJapanese ? `\u7533\u3057\u8A33\u3054\u3056\u3044\u307E\u305B\u3093\u3002\u300C${input3.substring(0, 50)}\u300D\u306E\u51E6\u7406\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F\u3002
14610
+
14611
+ \u5225\u306E\u65B9\u6CD5\u3067\u304A\u624B\u4F1D\u3044\u3057\u307E\u3059\uFF1A
14612
+ \u2022 \u8CEA\u554F\u3092\u8A00\u3044\u63DB\u3048\u3066\u304F\u3060\u3055\u3044
14613
+ \u2022 \u3088\u308A\u5177\u4F53\u7684\u306A\u8A73\u7D30\u3092\u63D0\u4F9B\u3057\u3066\u304F\u3060\u3055\u3044
14614
+ \u2022 \u8907\u96D1\u306A\u30EA\u30AF\u30A8\u30B9\u30C8\u306F\u5C0F\u3055\u304F\u5206\u5272\u3057\u3066\u304F\u3060\u3055\u3044
14615
+
14616
+ \u52B9\u679C\u7684\u306B\u30B5\u30DD\u30FC\u30C8\u3055\u305B\u3066\u3044\u305F\u3060\u304D\u307E\u3059\uFF01` : `I apologize, but I encountered an issue processing: "${input3.substring(0, 50)}"
11972
14617
 
11973
- Let me try to help you in a different way. Could you please:
11974
- \u2022 Rephrase your question or request
11975
- \u2022 Provide more specific details about what you need
11976
- \u2022 Break down complex requests into smaller parts
14618
+ Let me help you differently:
14619
+ \u2022 Rephrase your question
14620
+ \u2022 Provide more specific details
14621
+ \u2022 Break down complex requests
11977
14622
 
11978
14623
  I'm here to assist you effectively!`;
11979
14624
  }
@@ -37725,8 +40370,8 @@ var init_package = __esm({
37725
40370
  "package.json"() {
37726
40371
  package_default = {
37727
40372
  name: "@bonginkan/maria",
37728
- version: "3.1.4",
37729
- description: "\u{1F680} MARIA v3.1.4 - Minimal API, Maximum Power. Enterprise-ready AI development platform with beautiful CLI experience and rock-solid stability.",
40373
+ version: "3.1.6",
40374
+ description: "\u{1F4CA} MARIA v3.1.6 - Advanced Telemetry & Analytics. Enterprise AI platform with ML-powered monitoring, predictive analytics, and real-time insights.",
37730
40375
  keywords: [
37731
40376
  "ai",
37732
40377
  "cli",