a-basit commited on
Commit
0b766dd
·
verified ·
1 Parent(s): ddb9bb7

Update model_client.py

Browse files
Files changed (1) hide show
  1. model_client.py +33 -153
model_client.py CHANGED
@@ -1,153 +1,33 @@
1
- # backend/model_client.py
2
- import os
3
- import re
4
- import json
5
- import logging
6
- from dotenv import load_dotenv
7
- import requests
8
-
9
- load_dotenv()
10
-
11
- HF_API_KEY = os.getenv("HF_API_KEY")
12
- HF_MODEL = os.getenv("HF_MODEL", "deepseek-ai/DeepSeek-Coder-V2-Instruct")
13
- HF_BASE_URL = os.getenv("HF_BASE_URL", "https://api-inference.huggingface.co/models")
14
-
15
- if not HF_API_KEY:
16
- logging.warning("⚠️ HF_API_KEY not set. Please configure your .env file with your Hugging Face token.")
17
-
18
- SYSTEM_PROMPT = """
19
- You are CodeGen an assistant that converts natural language into robust automation scripts.
20
- Return exactly:
21
- 1) A single triple-backtick code block containing only the script.
22
- 2) Immediately after the code block, a JSON object with metadata:
23
- {
24
- "filename": "script.py",
25
- "language": "python",
26
- "description": "Short summary",
27
- "dependencies": ["imaplib"]
28
- }
29
- Rules:
30
- - Use placeholders for secrets (DO NOT include real credentials).
31
- - Add logging and helpful comments.
32
- - Avoid dangerous commands (rm -rf, format, shutdown, etc).
33
- - If the request is impossible, return an explanation inside the JSON `description` and an empty code block.
34
- """
35
-
36
- # Simple blacklist of dangerous tokens
37
- DANGEROUS_PATTERNS = [
38
- r"rm\s+-rf",
39
- r"Remove-Item\s+-Recurse",
40
- r"Format-Volume",
41
- r"shutdown",
42
- r"Format-Drive",
43
- r"DeleteFile",
44
- ]
45
-
46
- def hf_inference(prompt: str, max_new_tokens: int = 800, temperature: float = 0.0):
47
- """
48
- Call Hugging Face Inference API for the configured model.
49
- """
50
- url = f"{HF_BASE_URL}/{HF_MODEL}"
51
- headers = {"Authorization": f"Bearer {HF_API_KEY}"}
52
- payload = {
53
- "inputs": prompt,
54
- "parameters": {
55
- "max_new_tokens": max_new_tokens,
56
- "temperature": temperature,
57
- # you can tweak other model-specific parameters if needed
58
- },
59
- }
60
- # Many HF inference endpoints return a JSON list with a generated_text field.
61
- resp = requests.post(url, headers=headers, json=payload, timeout=120)
62
- resp.raise_for_status()
63
- data = resp.json()
64
- # data might be a list like [{"generated_text": "..."}] or plain text
65
- if isinstance(data, list) and "generated_text" in data[0]:
66
- return data[0]["generated_text"]
67
- # Some models / endpoints return plain dict or string
68
- if isinstance(data, dict) and "generated_text" in data:
69
- return data["generated_text"]
70
- if isinstance(data, str):
71
- return data
72
- # try to serialize if unknown structure
73
- return json.dumps(data)
74
-
75
- def parse_code_and_meta(llm_text: str):
76
- """
77
- Extract the first triple-backtick code block and the first JSON object after it.
78
- Returns (code_str, metadata_dict, raw_text)
79
- """
80
- code = ""
81
- meta = {}
82
- # find code block
83
- cb = re.search(r"```(?:\w+)?\n([\s\S]*?)```", llm_text)
84
- if cb:
85
- code = cb.group(1).strip()
86
- # find JSON object after code (first {...})
87
- jb = re.search(r"\{[\s\S]*\}", llm_text)
88
- if jb:
89
- try:
90
- meta = json.loads(jb.group(0))
91
- except Exception:
92
- # attempt to fix common python-style quotes etc
93
- try:
94
- cleaned = jb.group(0).replace("'", '"')
95
- meta = json.loads(cleaned)
96
- except Exception:
97
- meta = {}
98
- return code, meta, llm_text
99
-
100
- def check_safety(code_text: str):
101
- matches = []
102
- for pat in DANGEROUS_PATTERNS:
103
- if re.search(pat, code_text, re.IGNORECASE):
104
- matches.append(pat)
105
- return matches
106
-
107
- def generate_script(prompt: str, language: str = "python"):
108
- """
109
- Generate a script (Python or PowerShell) using a Hugging Face LLM model.
110
- """
111
-
112
- headers = {
113
- "Authorization": f"Bearer {HF_API_KEY}",
114
- "Content-Type": "application/json",
115
- }
116
-
117
- # Refined prompt for better structured output
118
- formatted_prompt = (
119
- f"Write a {language} script that accomplishes the following task:\n"
120
- f"Task: {prompt}\n"
121
- f"Include import statements, necessary libraries, and comments for clarity.\n"
122
- f"Provide the output in code block format only."
123
- )
124
-
125
- data = {"inputs": formatted_prompt}
126
-
127
- try:
128
- resp = requests.post(
129
- f"{HF_BASE_URL}/{HF_MODEL}",
130
- headers=headers,
131
- json=data,
132
- timeout=90
133
- )
134
- resp.raise_for_status()
135
- result = resp.json()
136
-
137
- # Some models return a list with 'generated_text', others return a dict
138
- if isinstance(result, list) and "generated_text" in result[0]:
139
- generated_code = result[0]["generated_text"]
140
- elif isinstance(result, dict) and "generated_text" in result:
141
- generated_code = result["generated_text"]
142
- else:
143
- generated_code = str(result)
144
-
145
- return {
146
- "ok": True,
147
- "code": generated_code.strip(),
148
- "raw": result
149
- }
150
-
151
- except requests.exceptions.RequestException as e:
152
- logging.error(f"Error calling HF Inference: {e}")
153
- return {"ok": False, "error": str(e), "raw": None}
 
1
+ import os
2
+ import requests
3
+ import logging
4
+
5
+ # Toggle between local Ollama or Hugging Face API
6
+ USE_OLLAMA = True
7
+
8
+ # Hugging Face config (optional)
9
+ HF_API_KEY = os.getenv("HF_API_KEY")
10
+ HF_MODEL = os.getenv("HF_MODEL", "HuggingFaceH4/zephyr-7b-beta")
11
+ HF_BASE_URL = os.getenv("HF_BASE_URL", "https://api-inference.huggingface.co/models")
12
+
13
+ # Ollama endpoint
14
+ OLLAMA_URL = "http://localhost:11434/api/generate"
15
+
16
+
17
+ def generate_script(prompt: str, language: str = "python") -> str:
18
+ """
19
+ Generate a structured AI response with:
20
+ - Problem statement
21
+ - Libraries required
22
+ - Script code
23
+ - Explanation
24
+ """
25
+
26
+ system_prompt = f"""
27
+ You are an expert automation engineer. When asked to generate a script, always respond in this exact structured format:
28
+
29
+ **Problem:** <2-3 lines summary of the task>
30
+ **Tech Used:** <language + libraries>
31
+ **Script:**
32
+ ```{language}
33
+ # code here