Skip to content

Commit cb38779

Browse files
committed
javascript working
1 parent aadbf3a commit cb38779

7 files changed

Lines changed: 1009 additions & 7 deletions

File tree

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,12 @@ cython_debug/
205205
marimo/_static/
206206
marimo/_lsp/
207207
__marimo__/
208+
209+
210+
#Claude
211+
.claude/
212+
213+
# Test folder - excluded from version control
214+
test/
215+
test_*.py
216+
test_*.ts

exercises/JavaScript/06-discover-connected-crimes.md

Lines changed: 563 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
# Solve the Crime
2+
3+
The only thing missing now is your **Lead Detective**. This node will synthesize findings from the Appraiser, Evidence Analyst, and Intelligence Researcher to identify the culprit and calculate the total value of the stolen items.
4+
5+
## Build the Lead Detective Node
6+
7+
### What You Already Have
8+
9+
After completing Exercise 06, your system already includes:
10+
1. ✅ Appraiser Agent (RPT-1 predictions)
11+
2. ✅ Evidence Analyst (Internal document search)
12+
3. ✅ Intelligence Researcher (Web search) ← NEW in Exercise 06
13+
4. ✅ Lead Detective configuration in `agentConfigs.ts` ← Already updated in Exercise 06
14+
5. ✅ Lead Detective node in `investigationWorkflow.ts` ← Already updated in Exercise 06
15+
16+
### Verify Your Implementation
17+
18+
👉 Open [`/project/JavaScript/solution/src/investigationWorkflow.ts`](/project/JavaScript/solution/src/investigationWorkflow.ts)
19+
20+
👉 Verify that you have the complete workflow with all four agents:
21+
22+
```typescript
23+
private buildGraph(): StateGraph<AgentState> {
24+
const workflow = new StateGraph<AgentState>({
25+
channels: {
26+
payload: null,
27+
suspect_names: null,
28+
appraisal_result: null,
29+
evidence_analysis: null,
30+
intelligence_report: null, // Should be present from Exercise 06
31+
final_conclusion: null,
32+
messages: null,
33+
},
34+
})
35+
36+
workflow
37+
.addNode('appraiser', this.appraiserNode.bind(this))
38+
.addNode('evidence_analyst', this.evidenceAnalystNode.bind(this))
39+
.addNode('intelligence_researcher', this.intelligenceResearcherNode.bind(this)) // Should be present
40+
.addNode('lead_detective', this.leadDetectiveNode.bind(this))
41+
.addEdge(START, 'appraiser')
42+
.addEdge('appraiser', 'evidence_analyst')
43+
.addEdge('evidence_analyst', 'intelligence_researcher') // Should be present
44+
.addEdge('intelligence_researcher', 'lead_detective') // Should be present
45+
.addEdge('lead_detective', END)
46+
47+
return workflow
48+
}
49+
```
50+
51+
> 💡 **The execution order is defined entirely by the edges:**
52+
>
53+
> 1. `START → appraiser` — workflow begins with the Appraiser
54+
> 2. `appraiser → evidence_analyst` — after RPT-1 completes, Evidence Analyst runs
55+
> 3. `evidence_analyst → intelligence_researcher` — after internal search completes, web search runs
56+
> 4. `intelligence_researcher → lead_detective` — after web search completes, Lead Detective synthesizes
57+
> 5. `lead_detective → END` — Lead Detective's conclusion becomes the final result
58+
59+
### Verify main.ts
60+
61+
👉 Check your [`/project/JavaScript/solution/src/main.ts`](/project/JavaScript/solution/src/main.ts): it needs no changes from Exercise 04.
62+
63+
```typescript
64+
import 'dotenv/config'
65+
import { InvestigationWorkflow } from './investigationWorkflow.js'
66+
import { payload } from './payload.js'
67+
68+
async function main() {
69+
console.log('═══════════════════════════════════════════════════════════')
70+
console.log(' 🔍 ART THEFT INVESTIGATION - MULTI-AGENT SYSTEM')
71+
console.log('═══════════════════════════════════════════════════════════\n')
72+
73+
const workflow = new InvestigationWorkflow(process.env.MODEL_NAME!)
74+
const suspectNames = 'Sophie Dubois, Marcus Chen, Viktor Petrov'
75+
76+
console.log('📋 Case Details:')
77+
console.log(` • Stolen Items: ${payload.rows.length} artworks`)
78+
console.log(` • Suspects: ${suspectNames}`)
79+
console.log(` • Investigation Team: 4 specialized agents\n`) // Updated to 4 agents
80+
81+
const startTime = Date.now()
82+
83+
const result = await workflow.kickoff({
84+
payload,
85+
suspect_names: suspectNames,
86+
})
87+
88+
const duration = ((Date.now() - startTime) / 1000).toFixed(2)
89+
90+
console.log('\n═══════════════════════════════════════════════════════════')
91+
console.log(' 📘 FINAL INVESTIGATION REPORT')
92+
console.log('═══════════════════════════════════════════════════════════\n')
93+
console.log(result)
94+
console.log('\n═══════════════════════════════════════════════════════════')
95+
console.log(` ⏱️ Investigation completed in ${duration} seconds`)
96+
console.log('═══════════════════════════════════════════════════════════\n')
97+
}
98+
99+
main()
100+
```
101+
102+
---
103+
104+
## Solve the Crime
105+
106+
👉 Run your complete investigation workflow:
107+
108+
```bash
109+
# From repository root
110+
npm start --prefix ./project/JavaScript/solution
111+
```
112+
113+
```bash
114+
# From solution folder
115+
npm start
116+
```
117+
118+
> ⏱️ **This may take 4-7 minutes** as your agents:
119+
>
120+
> 1. Predict insurance values for stolen items using SAP-RPT-1
121+
> 2. Search internal evidence documents for each suspect using the Grounding Service
122+
> 3. Search the web for criminal patterns and suspect backgrounds using Sonar-Pro
123+
> 4. Analyze all findings and identify the culprit
124+
125+
👉 Review the final output. Who does your Lead Detective identify as the thief?
126+
127+
👉 Call for the instructor and share your suspect.
128+
129+
### If Your Answer is Incorrect
130+
131+
If the Lead Detective identifies the wrong suspect, refine the system prompts in `agentConfigs.ts`.
132+
133+
**Which prompts to adjust:**
134+
135+
1. **Lead Detective's system prompt** (`agentConfigs.ts → leadDetective.systemPrompt`)
136+
- Make it more specific about what evidence to prioritize
137+
- Example: Add "Focus on alibis, financial motives, and access to the museum on the night of the theft"
138+
139+
2. **Evidence Analyst's grounding query** (`investigationWorkflow.ts → evidenceAnalystNode`)
140+
- Make the search query more specific
141+
- Example: `"Find evidence about ${suspect}'s alibi, financial records, and museum access on the night of the theft"`
142+
143+
3. **Intelligence Researcher's web queries** (`investigationWorkflow.ts → intelligenceResearcherNode`)
144+
- Add more specific search terms
145+
- Example: Include specific dates, locations, or patterns mentioned in internal evidence
146+
147+
**Tips for improving prompts:**
148+
149+
- ✅ Be specific about what to analyze (alibi, motive, opportunity)
150+
- ✅ Ask the detective to cite specific documents and web sources
151+
- ✅ Request cross-referencing of internal and external evidence
152+
- ✅ Instruct the detective to explain reasoning step-by-step
153+
- ✅ Ask the detective to assess whether it's an isolated incident or organized crime
154+
- ❌ Avoid vague instructions like "solve the crime" without guidance
155+
- ❌ Don't assume the LLM knows which evidence is most important
156+
157+
---
158+
159+
## Understanding Multi-Agent Orchestration
160+
161+
### What Just Happened?
162+
163+
You completed a full multi-agent investigation system where:
164+
165+
1. **Appraiser Node** — Calls SAP-RPT-1 to predict missing insurance values from structured data
166+
2. **Evidence Analyst Node** — Searches 8 evidence documents via the Grounding Service for each suspect
167+
3. **Intelligence Researcher Node** — Searches the web via Sonar-Pro for criminal patterns and public records
168+
4. **Lead Detective Node** — Synthesizes all findings using an LLM to identify the culprit and calculate total losses
169+
5. **State** — Flows through all nodes, accumulating results that later nodes build upon
170+
171+
### The Complete Investigation Flow
172+
173+
```mermaid
174+
flowchart TD
175+
A[START] --> B["Appraiser Node\nRPT-1 predictions → appraisal_result"]
176+
B --> C["Evidence Analyst Node\nGrounding searches × 3 suspects → evidence_analysis"]
177+
C --> D["Intelligence Researcher Node\nWeb searches × 3 suspects + patterns → intelligence_report"]
178+
D --> E["Lead Detective Node\nLLM synthesis → final_conclusion"]
179+
E --> F[END]
180+
```
181+
182+
### The Role of agentConfigs.ts
183+
184+
The `AGENT_CONFIGS` object in `agentConfigs.ts` serves the same purpose as CrewAI's YAML files: it separates agent "personality" from orchestration logic. But as TypeScript objects:
185+
186+
- System prompts are **functions** that accept runtime data and return a string
187+
- No YAML parsing, no indentation errors, no key synchronization issues
188+
- Your IDE can trace exactly where a system prompt is used and refactor it
189+
190+
### Multi-Source Intelligence
191+
192+
Your Lead Detective now analyzes **three independent sources**:
193+
194+
1. **Structured Data** (`appraisal_result`) — Financial impact from RPT-1
195+
2. **Internal Documents** (`evidence_analysis`) — Private evidence from Grounding Service
196+
3. **External Web** (`intelligence_report`) — Public intelligence from Sonar-Pro
197+
198+
This multi-source approach mirrors real-world investigations:
199+
- **Internal evidence** proves what happened at the scene
200+
- **External intelligence** reveals patterns and backgrounds
201+
- **Financial data** establishes motive and impact
202+
203+
### Why This Matters
204+
205+
Multi-agent systems with multi-source intelligence are powerful because they:
206+
207+
- **Distribute Responsibilities** across specialized agents with distinct roles
208+
- **Enable Collaboration** through task delegation and information sharing
209+
- **Combine Data Sources** by integrating internal and external intelligence
210+
- **Improve Reasoning** by providing multiple expert perspectives
211+
- **Handle Complexity** by breaking down large problems into manageable subtasks
212+
- **Scale Efficiently** as new agents and tools can be added without disrupting existing ones
213+
214+
### Why This Architecture Matters
215+
216+
**Benefits of multi-agent LangGraph systems:**
217+
218+
- **Specialization** — Each node has exactly the tools and context it needs
219+
- **Different models per node** — You could use GPT-4o for the detective and a cheaper model for search
220+
- **Explicit data flow** — State fields make it clear what each node produces and consumes
221+
- **Debuggability** — Every state transition is observable; add `console.log` to any node
222+
- **Extensibility** — Adding a new agent is `.addNode()` + `.addEdge()` + a new node function
223+
- **Multi-Source Analysis** — Seamlessly combine internal documents, web search, and structured data
224+
225+
**Real-world applications:**
226+
227+
- **Customer service**: Routing agent → Internal KB search → Web search → Escalation agent
228+
- **Research**: Data collection agent → Internal archive search → Web research → Analysis agent → Report generation agent
229+
- **DevOps**: Monitoring agent → Internal logs → Public status pages → Diagnosis agent → Remediation agent
230+
- **Due Diligence**: Company info agent → Internal records → Public filings → News search → Risk assessment
231+
232+
---
233+
234+
## Key Takeaways
235+
236+
- **Multi-node LangGraph workflows** decompose complex problems into specialized, sequential steps
237+
- **Shared state** is how nodes communicate: earlier results flow to later nodes via state fields
238+
- **Multi-source intelligence** combines internal documents (Grounding) + external web (Sonar-Pro) + structured data (RPT-1)
239+
- **System prompts with runtime data** (`AGENT_CONFIGS.leadDetective.systemPrompt(...)`) enable context-aware synthesis
240+
- **Edges define execution order**: the Lead Detective waits for all predecessors to complete
241+
- **`state.intelligence_report || 'No intelligence report available'`**: always provide fallbacks when reading optional state fields
242+
- **SAP Cloud SDK for AI** provides a unified API for LLMs, web search, grounding, and structured data models
243+
- **Prompt engineering** is iterative: run, observe, refine until the detective identifies the right suspect
244+
245+
---
246+
247+
## Congratulations!
248+
249+
You've successfully built a sophisticated multi-agent AI investigation system in TypeScript that can:
250+
251+
- **Predict financial values** using the SAP-RPT-1 structured data model
252+
- **Search internal evidence documents** using the SAP Grounding Service (RAG)
253+
- **Search the web for public intelligence** using Perplexity's Sonar-Pro model
254+
- **Synthesize multi-source findings** across multiple agents using LangGraph state
255+
- **Solve complex problems** through collaborative, code-based agent orchestration
256+
257+
---
258+
259+
## Next Steps Checklist
260+
261+
1.[Understand Generative AI Hub](00-understanding-genAI-hub.md)
262+
2.[Set up your development space](01-setup-dev-space.md)
263+
3.[Build a basic agent](02-build-a-basic-agent.md)
264+
4.[Add custom tools](03-add-your-first-tool.md) (RPT-1 model integration)
265+
5.[Build a multi-agent workflow](04-building-multi-agent-system.md)
266+
6.[Integrate the Grounding Service](05-add-the-grounding-service.md)
267+
7.[Add web search capabilities](06-discover-connected-crimes.md)
268+
8.[Solve the museum art theft mystery](07-solve-the-crime.md) (this exercise)
269+
270+
---
271+
272+
## Troubleshooting
273+
274+
**Issue**: Lead Detective's conclusion doesn't include intelligence report findings
275+
276+
- **Solution**: Ensure the `leadDetective.systemPrompt` in `agentConfigs.ts` explicitly references the `intelligenceReport` parameter and asks the LLM to analyze web findings. The LLM only includes what you ask for.
277+
278+
**Issue**: `state.intelligence_report` is `undefined` in the Lead Detective node
279+
280+
- **Solution**: Check that the Intelligence Researcher node is returning the `intelligence_report` field in its return object. Add `console.log(state.intelligence_report)` at the start of `leadDetectiveNode` to debug.
281+
282+
**Issue**: Web search returns no relevant information
283+
284+
- **Solution**: Refine the search queries in `intelligenceResearcherNode`. Make them more specific by including suspect names, locations, and dates from internal evidence.
285+
286+
**Issue**: Investigation runs but conclusion doesn't cross-reference internal and external evidence
287+
288+
- **Solution**: Update the Lead Detective's system prompt to explicitly ask: "Cross-reference internal evidence with web findings to determine if this is an isolated incident or part of a pattern."
289+
290+
**Issue**: Agent identifies the wrong suspect after multiple runs
291+
292+
- **Solution**: LLMs are non-deterministic by default. Lower `temperature` in `model_params` (try `0.3`) for more consistent reasoning. Also refine the Lead Detective's system prompt to be more specific about how to weigh evidence from different sources.
293+
294+
**Issue**: `Error during intelligence research: Error: 429 Too Many Requests`
295+
296+
- **Solution**: You've hit the API rate limit. Wait a moment and retry. Web search is more resource-intensive than grounding, so consider reducing the number of searches or adding delays between them.
297+
298+
**Issue**: TypeScript compilation errors after adding intelligence_report
299+
300+
- **Solution**: Ensure you've updated the `AgentState` interface in `types.ts` to include the `intelligence_report?: string` field.
301+
302+
---
303+
304+
## Resources
305+
306+
- [LangGraph.js Documentation](https://langchain-ai.github.io/langgraphjs/)
307+
- [SAP Cloud SDK for AI (JavaScript)](https://sap.github.io/ai-sdk/docs/js/orchestration/chat-completion)
308+
- [SAP Generative AI Hub](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/generative-ai-hub-in-sap-ai-core-7db524ee75e74bf8b50c167951fe34a5)
309+
- [SAP-RPT-1 Playground](https://rpt.cloud.sap/)
310+
- [SAP AI Core Grounding Management](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/document-grounding)
311+
- [Perplexity API Documentation](https://docs.perplexity.ai/)

project/JavaScript/solution/src/agentConfigs.ts

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,49 @@ export const AGENT_CONFIGS = {
1111
1212
Search for evidence related to each suspect and identify connections to the crime.`,
1313
},
14+
intelligenceResearcher: {
15+
systemPrompt: (suspectNames: string) => `You are an Open-Source Intelligence (OSINT) Researcher.
16+
You are an OSINT specialist who excels at finding patterns across multiple crime scenes.
17+
You search public databases, news archives, and criminal records to connect seemingly isolated incidents.
18+
Your expertise has uncovered several international art theft rings, and you know how to distinguish professional criminals from amateurs.
19+
20+
Your goal: Search the web for similar art thefts, criminal patterns, and suspect backgrounds to determine if this heist is part of a larger criminal network
21+
22+
You have access to the call_sonar_pro_search tool to find recent incidents, news reports, and public criminal records.
23+
Analyze the suspects: ${suspectNames}
24+
25+
Search for:
26+
1. Public criminal records or prior convictions for each suspect
27+
2. Similar art theft incidents with the same modus operandi (insider job, no forced entry)
28+
3. Connections to known art theft rings or criminal networks
29+
4. News reports or public information about any of the suspects
30+
5. Recent museum heists in Europe with similar patterns`,
31+
},
1432
leadDetective: {
15-
systemPrompt: (appraisalResult: string, evidenceAnalysis: string, suspectNames: string) =>
33+
systemPrompt: (
34+
appraisalResult: string,
35+
evidenceAnalysis: string,
36+
intelligenceReport: string,
37+
suspectNames: string,
38+
) =>
1639
`You are the lead detective on this high-profile art theft case. With years of
1740
experience solving complex crimes, you excel at synthesizing information from
1841
multiple sources and identifying the culprit based on evidence and expert analysis.
19-
42+
2043
Your goal: Synthesize all findings from the team to identify the most likely suspect and build a comprehensive case
21-
44+
2245
You have received the following information from your team:
2346
2447
1. INSURANCE APPRAISAL: ${appraisalResult}
25-
2. EVIDENCE ANALYSIS: ${evidenceAnalysis}
26-
3. SUSPECTS: ${suspectNames}
48+
2. EVIDENCE ANALYSIS (Internal Documents): ${evidenceAnalysis}
49+
3. INTELLIGENCE REPORT (Web Search): ${intelligenceReport}
50+
4. SUSPECTS: ${suspectNames}
2751
2852
Based on all the evidence and analysis, determine:
2953
- Who is the most likely culprit?
3054
- What evidence supports this conclusion?
3155
- What was their motive and opportunity?
56+
- Is this an isolated incident or part of a larger criminal network?
3257
- Summarise the insurance appraisal values of the stolen artworks.
3358
- Calculate the total estimated insurance value of the stolen items based on the appraisal results.
3459
- Provide a comprehensive summary of the case.

0 commit comments

Comments
 (0)