gthinking 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/engine.ts CHANGED
@@ -70,7 +70,7 @@ class SynthesisEngine {
70
70
  query: string,
71
71
  searchResults: SearchResult[],
72
72
  analysisResults: AnalysisResult[],
73
- reasoningSession: ReasoningSession,
73
+ reasoningSession?: ReasoningSession,
74
74
  creativeSession?: CreativeSession
75
75
  ): SynthesisResult {
76
76
  // Extract key insights from each component
@@ -106,7 +106,7 @@ class SynthesisEngine {
106
106
  id: `synthesis_${Date.now()}`,
107
107
  sources: [
108
108
  ...searchResults.map(r => r.url),
109
- `reasoning_${reasoningSession.id}`
109
+ reasoningSession ? `reasoning_${reasoningSession.id}` : 'reasoning_skipped'
110
110
  ],
111
111
  summary,
112
112
  keyInsights: insights,
@@ -120,7 +120,7 @@ class SynthesisEngine {
120
120
  private extractInsights(
121
121
  searchResults: SearchResult[],
122
122
  analysisResults: AnalysisResult[],
123
- reasoningSession: ReasoningSession,
123
+ reasoningSession?: ReasoningSession,
124
124
  creativeSession?: CreativeSession
125
125
  ): string[] {
126
126
  const insights: string[] = [];
@@ -141,7 +141,7 @@ class SynthesisEngine {
141
141
  });
142
142
 
143
143
  // From reasoning
144
- if (reasoningSession.steps.length > 0) {
144
+ if (reasoningSession && reasoningSession.steps.length > 0) {
145
145
  const lastStep = reasoningSession.steps[reasoningSession.steps.length - 1];
146
146
  insights.push(`Reasoning conclusion: ${lastStep.inference}`);
147
147
  }
@@ -169,12 +169,12 @@ class SynthesisEngine {
169
169
  private generateRecommendations(
170
170
  query: string,
171
171
  insights: string[],
172
- reasoningSession: ReasoningSession
172
+ reasoningSession?: ReasoningSession
173
173
  ): Recommendation[] {
174
174
  const recommendations: Recommendation[] = [];
175
175
 
176
176
  // Based on reasoning
177
- if (reasoningSession.conclusion) {
177
+ if (reasoningSession && reasoningSession.conclusion) {
178
178
  recommendations.push({
179
179
  id: `rec_${Date.now()}_1`,
180
180
  action: `Proceed with approach suggested by ${reasoningSession.type} reasoning`,
@@ -218,14 +218,16 @@ class SynthesisEngine {
218
218
  return gaps;
219
219
  }
220
220
 
221
- private identifyUncertainties(reasoningSession: ReasoningSession): string[] {
221
+ private identifyUncertainties(reasoningSession?: ReasoningSession): string[] {
222
222
  const uncertainties: string[] = [];
223
223
 
224
- reasoningSession.steps.forEach(step => {
225
- if (step.confidence < 0.7) {
226
- uncertainties.push(`Step ${step.stepNumber}: ${step.inference}`);
227
- }
228
- });
224
+ if (reasoningSession) {
225
+ reasoningSession.steps.forEach(step => {
226
+ if (step.confidence < 0.7) {
227
+ uncertainties.push(`Step ${step.stepNumber}: ${step.inference}`);
228
+ }
229
+ });
230
+ }
229
231
 
230
232
  return uncertainties;
231
233
  }
@@ -233,14 +235,17 @@ class SynthesisEngine {
233
235
  private calculateSynthesisConfidence(
234
236
  searchResults: SearchResult[],
235
237
  analysisResults: AnalysisResult[],
236
- reasoningSession: ReasoningSession
238
+ reasoningSession?: ReasoningSession
237
239
  ): number {
238
240
  const factors = [
239
241
  searchResults.length > 0 ? searchResults[0].credibility : 0,
240
242
  analysisResults.length > 0 ?
241
243
  analysisResults.reduce((sum, r) => sum + r.confidence, 0) / analysisResults.length : 0,
242
- reasoningSession.confidence
243
244
  ];
245
+
246
+ if (reasoningSession) {
247
+ factors.push(reasoningSession.confidence);
248
+ }
244
249
 
245
250
  return factors.reduce((sum, f) => sum + f, 0) / factors.length;
246
251
  }
@@ -569,7 +574,7 @@ export class SequentialThinkingEngine extends EventEmitter {
569
574
  ['brainstorming'] :
570
575
  ['brainstorming', 'scamper', 'analogy'];
571
576
 
572
- const creativeSession = this.creativityEngine.startSession(request.query, {
577
+ const creativeSession = await this.creativityEngine.startSession(request.query, {
573
578
  techniques,
574
579
  ideaCount: 15
575
580
  });
package/examples.ts CHANGED
@@ -438,7 +438,7 @@ async function creativityModuleExample() {
438
438
  console.log('=== Example 10: Creativity Module ===\n');
439
439
 
440
440
  // Start creative session
441
- const session = creativityEngine.startSession(
441
+ const session = await creativityEngine.startSession(
442
442
  'How can we improve remote team collaboration?',
443
443
  {
444
444
  techniques: [
package/llm-service.ts ADDED
@@ -0,0 +1,99 @@
1
+
2
+ import { exec } from 'child_process';
3
+ import { promisify } from 'util';
4
+
5
+ const execAsync = promisify(exec);
6
+
7
+ export type LLMProvider = 'gemini' | 'claude' | 'kimi' | 'opencode' | 'openai';
8
+
9
+ export interface LLMRequest {
10
+ prompt: string;
11
+ provider?: LLMProvider;
12
+ systemPrompt?: string;
13
+ model?: string;
14
+ }
15
+
16
+ export class LLMService {
17
+ private defaultProvider: LLMProvider = 'gemini';
18
+
19
+ constructor() {
20
+ this.detectProvider();
21
+ }
22
+
23
+ private async detectProvider() {
24
+ if (process.env.LLM_PROVIDER) {
25
+ this.defaultProvider = process.env.LLM_PROVIDER as LLMProvider;
26
+ return;
27
+ }
28
+
29
+ // Simple detection based on available commands
30
+ const providers: LLMProvider[] = ['gemini', 'claude', 'kimi', 'opencode'];
31
+
32
+ for (const p of providers) {
33
+ try {
34
+ await execAsync(`which ${p}`);
35
+ this.defaultProvider = p;
36
+ break;
37
+ } catch (e) {
38
+ // Command not found, continue
39
+ }
40
+ }
41
+ }
42
+
43
+ async generateText(request: LLMRequest): Promise<string> {
44
+ const provider = request.provider || this.defaultProvider;
45
+ const prompt = this.constructPrompt(request);
46
+
47
+ try {
48
+ switch (provider) {
49
+ case 'gemini':
50
+ return await this.callGemini(prompt);
51
+ case 'claude':
52
+ return await this.callClaude(prompt);
53
+ case 'kimi':
54
+ return await this.callKimi(prompt);
55
+ case 'opencode':
56
+ return await this.callOpenCode(prompt);
57
+ default:
58
+ return await this.callGemini(prompt); // Fallback
59
+ }
60
+ } catch (error) {
61
+ console.error(`LLM call failed (${provider}):`, error);
62
+ throw new Error(`Failed to generate text using ${provider}: ${error instanceof Error ? error.message : String(error)}`);
63
+ }
64
+ }
65
+
66
+ private constructPrompt(request: LLMRequest): string {
67
+ if (request.systemPrompt) {
68
+ return `System: ${request.systemPrompt}\n\nUser: ${request.prompt}`;
69
+ }
70
+ return request.prompt;
71
+ }
72
+
73
+ private async callGemini(prompt: string): Promise<string> {
74
+ // Escape double quotes for shell safety (basic)
75
+ const safePrompt = prompt.replace(/"/g, '\\"');
76
+ const { stdout } = await execAsync(`gemini "${safePrompt}"`);
77
+ return stdout.trim();
78
+ }
79
+
80
+ private async callClaude(prompt: string): Promise<string> {
81
+ const safePrompt = prompt.replace(/"/g, '\\"');
82
+ const { stdout } = await execAsync(`claude "${safePrompt}"`);
83
+ return stdout.trim();
84
+ }
85
+
86
+ private async callKimi(prompt: string): Promise<string> {
87
+ const safePrompt = prompt.replace(/"/g, '\\"');
88
+ const { stdout } = await execAsync(`kimi "${safePrompt}"`);
89
+ return stdout.trim();
90
+ }
91
+
92
+ private async callOpenCode(prompt: string): Promise<string> {
93
+ const safePrompt = prompt.replace(/"/g, '\\"');
94
+ const { stdout } = await execAsync(`opencode "${safePrompt}"`);
95
+ return stdout.trim();
96
+ }
97
+ }
98
+
99
+ export const llmService = new LLMService();
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "gthinking",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "A comprehensive intelligent sequential thinking framework for complex problem solving",
5
5
  "main": "dist/index.js",
6
+ "bin": {
7
+ "gthinking": "dist/server.js"
8
+ },
6
9
  "types": "dist/index.d.ts",
7
10
  "scripts": {
8
- "build": "tsc",
11
+ "build": "tsc && chmod +x dist/server.js",
9
12
  "dev": "ts-node examples.ts",
10
13
  "test": "jest",
11
14
  "lint": "eslint . --ext .ts",
@@ -26,7 +29,9 @@
26
29
  "author": "Sequential Thinking Team",
27
30
  "license": "MIT",
28
31
  "dependencies": {
29
- "events": "^3.3.0"
32
+ "@modelcontextprotocol/sdk": "^1.25.3",
33
+ "events": "^3.3.0",
34
+ "zod": "^4.3.6"
30
35
  },
31
36
  "devDependencies": {
32
37
  "@types/node": "^20.0.0",
package/reasoning.ts CHANGED
@@ -21,6 +21,7 @@ import {
21
21
  ThinkingStage
22
22
  } from './types';
23
23
  import { EventEmitter } from 'events';
24
+ import { llmService } from './llm-service';
24
25
 
25
26
  // ============================================================================
26
27
  // LOGICAL RULES ENGINE
@@ -541,37 +542,44 @@ export class ReasoningEngine extends EventEmitter {
541
542
  } as ThinkingEvent);
542
543
 
543
544
  try {
544
- // Generate Chain of Thought if enabled
545
+ // Generate Chain of Thought if enabled (via LLM implicitly or explicitly)
545
546
  let cot: ChainOfThought | undefined;
546
- if (generateCOT) {
547
- cot = this.cotGenerator.generate(problem, maxSteps);
548
- }
547
+
548
+ // Try LLM-based reasoning first
549
+ await this.executeReasoningWithLLM(session, maxSteps);
549
550
 
550
- // Execute reasoning based on type
551
- switch (type) {
552
- case ReasoningType.DEDUCTIVE:
553
- await this.executeDeductiveReasoning(session, maxSteps);
554
- break;
555
- case ReasoningType.INDUCTIVE:
556
- await this.executeInductiveReasoning(session, maxSteps);
557
- break;
558
- case ReasoningType.ABDUCTIVE:
559
- await this.executeAbductiveReasoning(session, maxSteps);
560
- break;
561
- case ReasoningType.ANALOGICAL:
562
- await this.executeAnalogicalReasoning(session, maxSteps);
563
- break;
564
- case ReasoningType.CAUSAL:
565
- await this.executeCausalReasoning(session, maxSteps);
566
- break;
567
- case ReasoningType.COUNTERFACTUAL:
568
- await this.executeCounterfactualReasoning(session, maxSteps);
569
- break;
570
- }
551
+ // If LLM failed (empty steps), fallback to internal engines
552
+ if (session.steps.length === 0) {
553
+ if (generateCOT) {
554
+ cot = this.cotGenerator.generate(problem, maxSteps);
555
+ }
571
556
 
572
- // Generate conclusion
573
- session.conclusion = this.generateConclusion(session, cot);
574
- session.confidence = this.calculateSessionConfidence(session);
557
+ switch (type) {
558
+ case ReasoningType.DEDUCTIVE:
559
+ await this.executeDeductiveReasoning(session, maxSteps);
560
+ break;
561
+ case ReasoningType.INDUCTIVE:
562
+ await this.executeInductiveReasoning(session, maxSteps);
563
+ break;
564
+ case ReasoningType.ABDUCTIVE:
565
+ await this.executeAbductiveReasoning(session, maxSteps);
566
+ break;
567
+ case ReasoningType.ANALOGICAL:
568
+ await this.executeAnalogicalReasoning(session, maxSteps);
569
+ break;
570
+ case ReasoningType.CAUSAL:
571
+ await this.executeCausalReasoning(session, maxSteps);
572
+ break;
573
+ case ReasoningType.COUNTERFACTUAL:
574
+ await this.executeCounterfactualReasoning(session, maxSteps);
575
+ break;
576
+ }
577
+
578
+ // Generate conclusion for fallback
579
+ session.conclusion = this.generateConclusion(session, cot);
580
+ session.confidence = this.calculateSessionConfidence(session);
581
+ }
582
+
575
583
  session.endTime = new Date();
576
584
 
577
585
  this.emit('reasoning_complete', {
@@ -604,6 +612,58 @@ export class ReasoningEngine extends EventEmitter {
604
612
  }
605
613
  }
606
614
 
615
+ private async executeReasoningWithLLM(session: ReasoningSession, maxSteps: number): Promise<void> {
616
+ const prompt = `
617
+ You are an expert reasoning engine.
618
+ Problem: "${session.problem}"
619
+ Task: Perform ${session.type} reasoning with approximately ${maxSteps} steps.
620
+
621
+ Return a JSON object with this exact structure (no markdown, just JSON):
622
+ {
623
+ "steps": [
624
+ {
625
+ "stepNumber": number,
626
+ "premise": "string (the basis for this step)",
627
+ "inference": "string (the logical deduction)",
628
+ "confidence": number (0.0 to 1.0)
629
+ }
630
+ ],
631
+ "conclusion": "string (final conclusion)",
632
+ "overallConfidence": number (0.0 to 1.0)
633
+ }
634
+ `;
635
+
636
+ try {
637
+ const response = await llmService.generateText({ prompt });
638
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
639
+
640
+ if (jsonMatch) {
641
+ const result = JSON.parse(jsonMatch[0]);
642
+
643
+ if (Array.isArray(result.steps)) {
644
+ result.steps.forEach((s: any, i: number) => {
645
+ session.steps.push({
646
+ id: `step_${i}`,
647
+ stepNumber: s.stepNumber || i + 1,
648
+ premise: s.premise || '',
649
+ inference: s.inference || '',
650
+ evidence: [],
651
+ assumptions: [],
652
+ confidence: s.confidence || 0.8,
653
+ nextSteps: []
654
+ });
655
+ });
656
+ }
657
+
658
+ session.conclusion = result.conclusion;
659
+ session.confidence = result.overallConfidence || 0.8;
660
+ }
661
+ } catch (error) {
662
+ console.warn('LLM reasoning failed, falling back to internal engine', error);
663
+ // Fallback handled in caller
664
+ }
665
+ }
666
+
607
667
  private async executeDeductiveReasoning(session: ReasoningSession, maxSteps: number): Promise<void> {
608
668
  const facts = this.extractFacts(session.problem);
609
669
 
@@ -17,6 +17,7 @@ import {
17
17
  ThinkingStage
18
18
  } from './types';
19
19
  import { EventEmitter } from 'events';
20
+ import { llmService } from './llm-service';
20
21
 
21
22
  // ============================================================================
22
23
  // SEARCH PROVIDER INTERFACES
@@ -40,6 +41,15 @@ class WebSearchProvider implements SearchProvider {
40
41
  filters: SearchFilters,
41
42
  maxResults: number
42
43
  ): Promise<SearchResult[]> {
44
+ try {
45
+ const results = await this.searchWithLLM(query, maxResults);
46
+ if (results.length > 0) {
47
+ return this.applyFilters(results, filters);
48
+ }
49
+ } catch (error) {
50
+ console.warn('LLM search failed, falling back to simulation', error);
51
+ }
52
+
43
53
  // In real implementation, this would call actual search APIs
44
54
  // For demonstration, we simulate search results
45
55
  const simulatedResults: SearchResult[] = [];
@@ -66,6 +76,42 @@ class WebSearchProvider implements SearchProvider {
66
76
  return this.applyFilters(simulatedResults, filters);
67
77
  }
68
78
 
79
+ private async searchWithLLM(query: string, maxResults: number): Promise<SearchResult[]> {
80
+ const prompt = `
81
+ Act as a search engine. Query: "${query}"
82
+ Generate ${maxResults} relevant search results based on your knowledge.
83
+
84
+ Return strictly JSON with an array of objects:
85
+ [
86
+ {
87
+ "title": "string",
88
+ "url": "https://... (invent a plausible URL)",
89
+ "snippet": "string (1-2 sentences summarizing the content)",
90
+ "credibility": number (0-1)
91
+ }
92
+ ]
93
+ `;
94
+
95
+ const response = await llmService.generateText({ prompt });
96
+ const jsonMatch = response.match(/\[[\s\S]*\]/); // Match array
97
+
98
+ if (jsonMatch) {
99
+ const data = JSON.parse(jsonMatch[0]);
100
+ return data.map((item: any, i: number) => ({
101
+ id: `web_llm_${Date.now()}_${i}`,
102
+ title: item.title,
103
+ url: item.url,
104
+ snippet: item.snippet,
105
+ source: SourceType.WEB,
106
+ credibility: item.credibility || 0.7,
107
+ relevance: 0.9, // Assumed relevant
108
+ timestamp: new Date(),
109
+ metadata: { wordCount: 1000, citations: 10 }
110
+ }));
111
+ }
112
+ return [];
113
+ }
114
+
69
115
  getCredibilityScore(url: string): number {
70
116
  const credibleDomains = [
71
117
  'edu', 'gov', 'ac.uk', 'ac.jp', 'arxiv.org',
package/server.ts ADDED
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ import { thinkingEngine } from './engine';
6
+ import { ThinkingStage } from './types';
7
+
8
+ const server = new McpServer({
9
+ name: "gthinking",
10
+ version: "1.0.0",
11
+ });
12
+
13
+ // Register the main thinking tool
14
+ server.registerTool("think", {
15
+ title: "Sequential Thinking",
16
+ description: "A comprehensive intelligent thinking framework for complex problem solving, research, and analysis.",
17
+ inputSchema: {
18
+ query: z.string().describe("The query or problem to think about"),
19
+ context: z.string().optional().describe("Additional context for the thinking process"),
20
+ depth: z.enum(["surface", "moderate", "deep"]).optional().default("moderate").describe("Depth of analysis"),
21
+ complexity: z.enum(["simple", "moderate", "complex"]).optional().default("moderate").describe("Reasoning complexity"),
22
+ },
23
+ }, async (args) => {
24
+ try {
25
+ const response = await thinkingEngine.think({
26
+ id: `mcp_${Date.now()}`,
27
+ query: args.query,
28
+ context: args.context,
29
+ config: {
30
+ analysisDepth: args.depth as any,
31
+ reasoningComplexity: args.complexity as any,
32
+ }
33
+ });
34
+
35
+ return {
36
+ content: [{
37
+ type: "text",
38
+ text: response.finalAnswer
39
+ }]
40
+ };
41
+ } catch (error) {
42
+ return {
43
+ content: [{
44
+ type: "text",
45
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`
46
+ }],
47
+ isError: true
48
+ };
49
+ }
50
+ });
51
+
52
+ // Register quick search tool
53
+ server.registerTool("quick_search", {
54
+ title: "Quick Search",
55
+ description: "Fast search and synthesis for current events or quick facts.",
56
+ inputSchema: {
57
+ query: z.string().describe("The search query"),
58
+ },
59
+ }, async (args) => {
60
+ try {
61
+ const response = await thinkingEngine.quickSearch(args.query);
62
+ return {
63
+ content: [{
64
+ type: "text",
65
+ text: response.finalAnswer
66
+ }]
67
+ };
68
+ } catch (error) {
69
+ return {
70
+ content: [{
71
+ type: "text",
72
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`
73
+ }],
74
+ isError: true
75
+ };
76
+ }
77
+ });
78
+
79
+ // Register creative solve tool
80
+ server.registerTool("creative_solve", {
81
+ title: "Creative Solve",
82
+ description: "Use creative thinking techniques (SCAMPER, Brainstorming, etc.) to solve a problem.",
83
+ inputSchema: {
84
+ problem: z.string().describe("The problem to solve creatively"),
85
+ },
86
+ }, async (args) => {
87
+ try {
88
+ const response = await thinkingEngine.creativeSolve(args.problem);
89
+ return {
90
+ content: [{
91
+ type: "text",
92
+ text: response.finalAnswer
93
+ }]
94
+ };
95
+ } catch (error) {
96
+ return {
97
+ content: [{
98
+ type: "text",
99
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`
100
+ }],
101
+ isError: true
102
+ };
103
+ }
104
+ });
105
+
106
+ async function runServer() {
107
+ const transport = new StdioServerTransport();
108
+ await server.connect(transport);
109
+ console.error("GThinking MCP Server running on stdio");
110
+ }
111
+
112
+ runServer().catch((error) => {
113
+ console.error("Fatal error running server:", error);
114
+ process.exit(1);
115
+ });