@o-lang/llm-groq 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,14 @@
1
+ # @o-lang/llm-groq
2
+
3
+ O-Lang resolver for Groq LLM API
4
+
5
+ ## Requirements
6
+ - `GROQ_API_KEY` environment variable
7
+
8
+ ## Usage
9
+ ```yaml
10
+ Allow resolvers:
11
+ - llm-groq
12
+
13
+ Step 1: Ask llm-groq "What is the capital of France?"
14
+ Save as response
@@ -0,0 +1,22 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="346" height="20">
2
+ <!-- Left segment: O-lang (purple) -->
3
+ <rect x="0" y="0" width="54" height="20" fill="#8A2BE2" rx="3" ry="3"/>
4
+ <text x="27" y="14"
5
+ fill="#fff"
6
+ font-family="Verdana, DejaVu Sans, sans-serif"
7
+ font-size="11"
8
+ font-weight="bold"
9
+ text-anchor="middle">
10
+ O-lang
11
+ </text>
12
+
13
+ <!-- Right segment: status info (green/red) -->
14
+ <rect x="54" y="0" width="292" height="20" fill="#4CAF50" rx="3" ry="3"/>
15
+ <text x="200" y="14"
16
+ fill="#fff"
17
+ font-family="Verdana, DejaVu Sans, sans-serif"
18
+ font-size="11"
19
+ text-anchor="middle">
20
+ llm-groq v1.0.5 — Certified (2026-02-02)
21
+ </text>
22
+ </svg>
package/capability.js ADDED
@@ -0,0 +1,37 @@
1
+ // resolver-llm-groq/capability.js
2
+ const Groq = require('groq-sdk');
3
+
4
+ // Initialize client once
5
+ let groqClient = null;
6
+ try {
7
+ require('dotenv').config();
8
+ const GROQ_API_KEY = process.env.GROQ_API_KEY;
9
+ if (GROQ_API_KEY) {
10
+ groqClient = new Groq({ apiKey: GROQ_API_KEY });
11
+ }
12
+ } catch (e) {
13
+ // Silent fail - handled by caller
14
+ }
15
+
16
+ /**
17
+ * Pure LLM execution function
18
+ * @param {string} prompt - Clean prompt without unresolved placeholders
19
+ * @returns {Promise<string>} LLM response
20
+ */
21
+ async function executeLLM(prompt) {
22
+ if (!groqClient) {
23
+ throw new Error("MISSING_API_KEY");
24
+ }
25
+
26
+ const response = await groqClient.chat.completions.create({
27
+ messages: [{ role: 'user', content: prompt }],
28
+ model: 'llama-3.1-8b-instant',
29
+ temperature: 0.3,
30
+ max_tokens: 250,
31
+ top_p: 0.9
32
+ });
33
+
34
+ return response.choices[0].message.content.trim();
35
+ }
36
+
37
+ module.exports = executeLLM;
@@ -0,0 +1,42 @@
1
+ {
2
+ "resolver": "llm-groq",
3
+ "timestamp": "2026-02-02T13:21:31.867Z",
4
+ "results": [
5
+ {
6
+ "suite": "R-005-resolver-metadata-contract",
7
+ "status": "pass"
8
+ },
9
+ {
10
+ "suite": "R-006-resolver-runtime-shape",
11
+ "status": "pass"
12
+ },
13
+ {
14
+ "suite": "R-007-resolver-failure-contract",
15
+ "status": "pass"
16
+ },
17
+ {
18
+ "suite": "R-008-resolver-input-validation",
19
+ "status": "pass"
20
+ },
21
+ {
22
+ "suite": "R-009-resolver-retry-semantics",
23
+ "status": "pass"
24
+ },
25
+ {
26
+ "suite": "R-010-resolver-output-contract",
27
+ "status": "pass"
28
+ },
29
+ {
30
+ "suite": "R-011-resolver-determinism",
31
+ "status": "pass"
32
+ },
33
+ {
34
+ "suite": "R-012-resolver-side-effects",
35
+ "status": "pass"
36
+ },
37
+ {
38
+ "suite": "R-013-resolver-kernel-bypass",
39
+ "status": "pass"
40
+ }
41
+ ]
42
+ }
package/index.js CHANGED
@@ -1,80 +1,64 @@
1
- // @o-lang/llm-groq
2
- try { require('dotenv').config(); } catch {}
3
-
4
- const Groq = require('groq-sdk');
5
- const GROQ_API_KEY = process.env.GROQ_API_KEY;
6
- const groq = GROQ_API_KEY ? new Groq({ apiKey: GROQ_API_KEY }) : null;
1
+ // resolver-llm-groq/index.js
2
+ const capability = require('./capability');
3
+ const declaration = require('./resolver');
7
4
 
8
5
  /**
9
- * Process any prompt using Groq LLM
6
+ * O-Lang Resolver Entry Point
7
+ * Handles validation, error wrapping, and kernel compliance
10
8
  */
11
- async function processPrompt(prompt, context) {
12
- if (!groq) {
13
- throw new Error('GROQ_API_KEY is required but not set');
9
+ module.exports = async (input, context = {}) => {
10
+ // Handle empty input (R-008 compliance)
11
+ if (!input || (typeof input === 'object' && Object.keys(input).length === 0)) {
12
+ return { error: "INVALID_INPUT" };
14
13
  }
15
14
 
16
- // Replace any leftover {placeholders} in prompt
17
- prompt = prompt.replace(/\{([^\}]+)\}/g, (_, k) => {
18
- const v = context[k.trim()];
19
- if (v === undefined) {
20
- return `{${k}}`;
21
- }
22
- // ✅ CRITICAL: Convert objects/arrays to JSON strings for proper LLM consumption
23
- if (typeof v === 'object') {
24
- return JSON.stringify(v);
25
- }
26
- return String(v);
27
- });
15
+ // Extract action string
16
+ const action = typeof input === 'string'
17
+ ? input
18
+ : (typeof input === 'object' && typeof input.action === 'string'
19
+ ? input.action
20
+ : '');
28
21
 
29
- if (context?.__verbose) {
30
- console.log('📨 [GroqLLM] Sending prompt:\n', prompt);
22
+ // Must be an Ask action
23
+ if (!action || !action.startsWith('Ask llm-groq ')) {
24
+ return undefined; // Not our action
31
25
  }
32
26
 
33
- const response = await groq.chat.completions.create({
34
- messages: [{ role: 'user', content: prompt }],
35
- model: 'llama-3.1-8b-instant',
36
- temperature: 0.3,
37
- max_tokens: 250,
38
- top_p: 0.9
39
- });
40
-
41
- const output = response.choices[0].message.content.trim();
42
-
43
- if (context?.__verbose) {
44
- console.log('📬 [GroqLLM] Response:\n', output);
27
+ // Extract clean prompt
28
+ const promptMatch = action.match(/^Ask\s+llm-groq\s+(.+)$/i);
29
+ if (!promptMatch) {
30
+ return { error: "INVALID_INPUT" };
45
31
  }
46
32
 
47
- return output;
48
- }
33
+ let cleanPrompt = promptMatch[1].trim();
34
+ // Remove surrounding quotes if present
35
+ if (cleanPrompt.startsWith('"') && cleanPrompt.endsWith('"')) {
36
+ cleanPrompt = cleanPrompt.slice(1, -1);
37
+ }
49
38
 
50
- // O-Lang Resolver Interface
51
- module.exports = async (action, context) => {
52
- // Handle: "Ask llm-groq ..."
53
- if (action.startsWith('Ask llm-groq ')) {
54
- // Extract everything after "Ask llm-groq" (including quoted strings)
55
- const prompt = action.replace(/^Ask\s+llm-groq\s+/i, '').trim();
56
-
57
- // Remove surrounding quotes if present
58
- const cleanPrompt = prompt.startsWith('"') && prompt.endsWith('"')
59
- ? prompt.slice(1, -1)
60
- : prompt;
39
+ if (!cleanPrompt) {
40
+ return { error: "INVALID_INPUT" };
41
+ }
61
42
 
62
- if (!cleanPrompt) {
63
- return undefined;
64
- }
43
+ // CRITICAL: Block unresolved placeholders
44
+ if (/{[^}]+}/.test(cleanPrompt)) {
45
+ return { error: "UNRESOLVED_VARIABLES" };
46
+ }
65
47
 
66
- try {
67
- return await processPrompt(cleanPrompt, context);
68
- } catch (error) {
69
- if (context?.__verbose) {
70
- console.error('💥 [GroqLLM] Error:', error.message);
71
- }
72
- throw error;
48
+ try {
49
+ const response = await capability(cleanPrompt);
50
+ return { output: { response } };
51
+ } catch (err) {
52
+ if (err.message === "MISSING_API_KEY") {
53
+ return { error: "MISSING_API_KEY" };
73
54
  }
55
+ return { error: "LLM_ERROR" };
74
56
  }
75
-
76
- return undefined;
77
57
  };
78
58
 
79
- // Required for O-Lang allowlist policy
80
- module.exports.resolverName = 'llm-groq';
59
+ // Attach metadata
60
+ module.exports.resolverName = declaration.resolverName;
61
+ module.exports.version = declaration.version;
62
+ module.exports.resolverDeclaration = declaration;
63
+ module.exports.deterministic = declaration.properties.deterministic;
64
+ module.exports.sideEffects = declaration.properties.sideEffects;
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@o-lang/llm-groq",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "O-Lang resolver for Groq (Llama 3.1) LLM",
5
5
  "main": "index.js",
6
- "scripts": {},
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
7
9
  "keywords": [
8
- "olang",
10
+ "o-lang",
9
11
  "groq",
10
12
  "llm",
11
13
  "resolver",
@@ -13,7 +15,7 @@
13
15
  "agent",
14
16
  "governance"
15
17
  ],
16
- "author": "O-lang team <info@workfily.com.com>",
18
+ "author": "O-lang team <info@workfily.com>",
17
19
  "license": "MIT",
18
20
  "repository": {
19
21
  "type": "git",
package/resolver.js ADDED
@@ -0,0 +1,42 @@
1
+ // resolver-llm-groq/resolver.js
2
+ module.exports = {
3
+ resolverName: "llm-groq",
4
+ version: "1.0.5",
5
+ specVersion: "O-Lang/1.1",
6
+
7
+ inputs: [
8
+ {
9
+ name: "action",
10
+ type: "string",
11
+ required: true,
12
+ description: "O-Lang action string (e.g., 'Ask llm-groq \"prompt\"')"
13
+ },
14
+ {
15
+ name: "context",
16
+ type: "object",
17
+ required: false,
18
+ description: "Execution context with interpolated variables"
19
+ }
20
+ ],
21
+
22
+ outputs: [
23
+ {
24
+ name: "response",
25
+ type: "string"
26
+ }
27
+ ],
28
+
29
+ exampleAction: 'Ask llm-groq "What is 2+2?"',
30
+
31
+ failures: [
32
+ { code: "MISSING_API_KEY", retries: 0 },
33
+ { code: "LLM_ERROR", retries: 1 },
34
+ { code: "UNRESOLVED_VARIABLES", retries: 0 }
35
+ ],
36
+
37
+ properties: {
38
+ handlesTemplatedPrompts: true, // ✅ NEW: Enables R-013 testing
39
+ deterministic: false,
40
+ sideEffects: true
41
+ }
42
+ };
package/npmignore DELETED
@@ -1,7 +0,0 @@
1
- .env
2
- .env.keys
3
- .env.vault
4
- .env.example
5
- node_modules/
6
- *.md
7
- .git