elly99 commited on
Commit
93bd556
·
verified ·
1 Parent(s): 6ab6730

Create pipeline/agi_cognitive_pipeline.py

Browse files
src/pipeline/agi_cognitive_pipeline.py ADDED
@@ -0,0 +1,303 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # © 2025 Elena Marziali — Code released under Apache 2.0 license.
2
+ # See LICENSE in the repository for details.
3
+ # Removal of this copyright is prohibited.
4
+
5
+ # This cell simulates AGI (Artificial General Intelligence) behavior,
6
+ # with capabilities for planning, reasoning, generation, and self-assessment.
7
+
8
+ # Interactive loop simulating a complete cognitive cycle
9
+ async def agi_interactive_loop(user_input):
10
+ context = retrieve_multiturn_context(user_input, top_k=3)
11
+ planning = decompose_task(user_input)
12
+ results = []
13
+
14
+ for subtask in planning:
15
+ response = await generate_agi_response(subtask, context)
16
+ results.append(response)
17
+ update_memory(subtask, response)
18
+
19
+ return synthesize_final(results)
20
+
21
+
22
+ cross_encoder = CrossEncoder("cross-encoder/nli-deberta-base")
23
+
24
+ # Simulated historical archive for the question
25
+ memory_archive = {}
26
+
27
+ # Evaluate and version the generated response
28
+ def evaluate_and_version_response(question, new_response, level="basic", acceptance_threshold=0.75):
29
+ """
30
+ Evaluates a new response using CrossEncoder,
31
+ compares it with previous versions,
32
+ and decides whether to keep or discard it.
33
+
34
+ Returns a dictionary with:
35
+ - evaluation outcome
36
+ - version details (if accepted)
37
+ - confidence and note (if discarded)
38
+ """
39
+
40
+ question_id = question.strip().lower()
41
+
42
+ # Step 1: Semantic evaluation of the new response
43
+ new_score = float(cross_encoder.predict([(question, new_response)])[0])
44
+
45
+ new_version = {
46
+ "id": str(uuid.uuid4()),
47
+ "response": new_response,
48
+ "coherence_score": round(new_score, 3),
49
+ "level": level,
50
+ "timestamp": datetime.datetime.utcnow().isoformat(),
51
+ "model_version": "LLM_v1",
52
+ "improvable": new_score < acceptance_threshold
53
+ }
54
+
55
+ # Step 2: Retrieve previous versions
56
+ previous_memory = memory_archive.get(question_id, [])
57
+
58
+ # If no previous versions exist, save the first one
59
+ if not previous_memory:
60
+ memory_archive[question_id] = [new_version]
61
+ return {
62
+ "outcome": "New question saved.",
63
+ "total_versions": 1,
64
+ "response_accepted": True,
65
+ "details": new_version
66
+ }
67
+
68
+ # Step 3: Compare with the best saved version
69
+ best_version = max(previous_memory, key=lambda v: v["coherence_score"])
70
+ best_score = best_version["coherence_score"]
71
+
72
+ if new_score > best_score:
73
+ memory_archive[question_id].append(new_version)
74
+ return {
75
+ "outcome": "New version saved (more coherent than previous).",
76
+ "total_versions": len(memory_archive[question_id]),
77
+ "response_accepted": True,
78
+ "details": new_version
79
+ }
80
+
81
+ # Version discarded: less coherent
82
+ return {
83
+ "outcome": "Version discarded: less coherent than existing ones.",
84
+ "response_accepted": False,
85
+ "confidence": round(new_score, 3),
86
+ "note": "The proposed version is less coherent than the previous one.",
87
+ "new_score": round(new_score, 3),
88
+ "best_score": round(best_score, 3)
89
+ }
90
+
91
+
92
+ # === Main function: hypothesis generation and creative analysis ===
93
+ def simulate_scientific_creativity(concept, subject, style="generative", level="advanced", language="it"):
94
+ prompt = f"""
95
+ You are a cognitive scientific assistant with autonomous creative capabilities.
96
+
97
+ Subject: {subject}
98
+ Central concept: {concept}
99
+ Requested creative style: {style}
100
+ Level: {level}
101
+
102
+ Objective: Generate an innovative scientific proposal.
103
+
104
+ Respond with:
105
+ 1. An **original hypothesis** related to "{concept}".
106
+ 2. A **conceptual model** that can be visually described.
107
+ 3. A proposal for a **novel experiment** to test it.
108
+ 4. Possible **interdisciplinary applications**.
109
+ 5. A reflection on the degree of verifiability and impact.
110
+
111
+ Translate everything into language: **{language}**
112
+ """
113
+ try:
114
+ response = llm.invoke(prompt.strip())
115
+ hypothesis_text = getattr(response, "content", str(response)).strip()
116
+ return hypothesis_text
117
+ except Exception as e:
118
+ logging.error(f"[simulate_creativity] Generation error: {e}")
119
+ return "Error during creative simulation."
120
+
121
+ # === Classifications ===
122
+ problem_type = analyze_question(example_problem)
123
+ diagram_type_ml = extract_features(example_problem)
124
+ print(f"Problem type: {problem_type}")
125
+ print(f"Recommended representation: {diagram_type_ml}")
126
+
127
+ logging.info(f"Identified problem type: {problem_type}")
128
+ logging.info(f"Recommended representation type: {diagram_type_ml}")
129
+
130
+ # === Assign concept from the 'topic' variable ===
131
+ concept = topic.strip()
132
+
133
+ # === Retrieve articles from arXiv with error handling ===
134
+ try:
135
+ arxiv_articles = await search_arxiv_async(concept)
136
+ logging.info(f"arXiv: {len(arxiv_articles)} articles found.")
137
+ except Exception as e:
138
+ logging.error(f"Error during arXiv search: {e}")
139
+ arxiv_articles = []
140
+
141
+ # === Retrieve from other databases ===
142
+ try:
143
+ pubmed_results = await search_pubmed_async(concept)
144
+ openalex_results = await search_openalex_async(concept)
145
+
146
+ logging.info("Search completed across all databases.")
147
+ except Exception as e:
148
+ logging.error(f"Error in multi-database search: {e}")
149
+ pubmed_results = openalex_results = doaj_results = []
150
+
151
+ # === Formatting for prompt or report ===
152
+ async def retrieve_and_normalize_articles(concept):
153
+ """
154
+ Retrieves articles from multiple scientific sources and normalizes them.
155
+
156
+ Sources: arXiv, PubMed, OpenAlex, Zenodo
157
+
158
+ Returns:
159
+ - list of normalized articles
160
+ """
161
+ articles = []
162
+
163
+ try:
164
+ arxiv_articles = await search_arxiv_async(concept)
165
+ except Exception as e:
166
+ logging.error(f"[arxiv] Error: {e}")
167
+ arxiv_articles = []
168
+
169
+ try:
170
+ pubmed_articles = await search_pubmed_async(concept)
171
+ except Exception as e:
172
+ logging.error(f"[pubmed] Error: {e}")
173
+ pubmed_articles = []
174
+
175
+ try:
176
+ openalex_articles = await search_openalex_async(concept)
177
+ except Exception as e:
178
+ logging.error(f"[openalex] Error: {e}")
179
+ openalex_articles = []
180
+
181
+ try:
182
+ zenodo_articles = await search_zenodo_async(concept)
183
+ except Exception as e:
184
+ logging.error(f"[zenodo] Error: {e}")
185
+ zenodo_articles = []
186
+
187
+ sources = {
188
+ "arxiv": arxiv_articles,
189
+ "pubmed": pubmed_articles,
190
+ "openalex": openalex_articles,
191
+ "zenodo": zenodo_articles
192
+ }
193
+
194
+ for name, source in sources.items():
195
+ if isinstance(source, list) and all(isinstance(a, dict) for a in source):
196
+ articles += normalize_source(raw_articles=source, source_name=name)
197
+ else:
198
+ logging.warning(f"[{name}] Invalid data or unrecognized structure.")
199
+
200
+ logging.info(f"Total normalized articles: {len(articles)}")
201
+ return articles
202
+
203
+ # Check if articles exist and format the text
204
+ example_query = "quantum physics" # Define the query
205
+ articles = await search_multi_database(example_query)
206
+ zenodo_articles = await search_zenodo_async(example_query)
207
+
208
+ # === Prompt construction and response ===
209
+ # Perform academic database search
210
+ pubmed_results = await search_pubmed_async(concept)
211
+ openalex_results = await search_openalex_async(concept)
212
+ arxiv_results = await search_arxiv_async(concept)
213
+ zenodo_results = await search_zenodo_async(concept)
214
+
215
+ chart_choice_text = "Chart included" if chart_choice.lower() in ["yes"] else "Text only"
216
+
217
+ paper_text = "" # Or provide a predefined text
218
+
219
+ # Modify language handling in the prompt to avoid errors
220
+ prompt = prompt_template.format(
221
+ problem=example_problem,
222
+ topic=topic,
223
+ concept=concept,
224
+ level=level,
225
+ subject=subject,
226
+ arxiv_search=arxiv_results,
227
+ paper_text=paper_text,
228
+ pubmed_search=pubmed_results,
229
+ zenodo_search=zenodo_results,
230
+ openalex_search=openalex_results,
231
+ chart_choice=chart_choice_text,
232
+ target_language=target_language
233
+ )
234
+
235
+ try:
236
+ # Generate response
237
+ response = llm.invoke(prompt.strip())
238
+ response_content = getattr(response, "content", str(response))
239
+
240
+ if not response_content or "Error" in response_content:
241
+ raise ValueError("Invalid AI model response")
242
+ logging.info("Response successfully generated.")
243
+
244
+ # Reasoning explanation (metacognition)
245
+ reasoning_explanation = explain_reasoning(prompt, response_content)
246
+ print("Reasoning explanation:\n", getattr(reasoning_explanation, "content", reasoning_explanation))
247
+
248
+ # Operational decision (AGI Point 5)
249
+ objective = generate_objective_from_input(example_problem)
250
+ decision = llm.invoke(f"Objective: {objective}\nPrompt: {prompt.strip()}")
251
+ action = getattr(decision, "content", str(decision)).strip()
252
+ print(f"Agent's autonomous decision: {action}")
253
+
254
+ except Exception as e:
255
+ logging.error(f"General error in AGI operational block: {e}")
256
+
257
+
258
+ # This cell executes a generation + metacognition cycle
259
+
260
+ final_response = metacognitive_cycle(example_problem, level)
261
+
262
+ # Generates and evaluates the response for coherence and potential improvement
263
+ def generate_and_evaluate(generation_prompt, question, level):
264
+ response = llm.invoke(generation_prompt)
265
+ evaluation_prompt = f"""
266
+ You received the following response: "{getattr(response, 'content', response)}".
267
+ - Is it coherent with the question: "{question}"?
268
+ - Is the tone appropriate for the '{level}' level?
269
+ - How would you improve the response?
270
+ """
271
+ feedback = llm.invoke(evaluation_prompt)
272
+ return response, feedback
273
+
274
+ import time
275
+
276
+ def execute_with_retry(function, max_attempts=3, base_delay=2):
277
+ for attempt in range(max_attempts):
278
+ try:
279
+ return function()
280
+ except InternalServerError as e:
281
+ logging.warning(f"Attempt {attempt+1} failed: {e}")
282
+ time.sleep(base_delay * (attempt + 1))
283
+ except Exception as e:
284
+ logging.error(f"Unhandled error: {e}")
285
+ break
286
+ return "Persistent error: unable to complete the operation."
287
+
288
+
289
+ # === Visualization (optional) ===
290
+ if chart_requested and diagram_type_ml in ["Chart", "Conceptual diagram", "State diagram"]:
291
+ logging.info("Generating interactive chart...")
292
+ try:
293
+ fig, caption = generate_interactive_chart(example_problem)
294
+ fig.show()
295
+ logging.info("Chart successfully generated!")
296
+ except Exception as e:
297
+ logging.error(f"Error during chart generation: {e}")
298
+ else:
299
+ logging.info("Chart not requested or not necessary.")
300
+
301
+
302
+ from IPython.display import FileLink
303
+ FileLink(file_name)