From af5be552bb14744e91a26468c043145ab2cd0290 Mon Sep 17 00:00:00 2001 From: D062408 Date: Tue, 31 Mar 2026 14:40:52 +0200 Subject: [PATCH] add minor fixes to JS/TS Exercise --- .../JavaScript/03-add-your-first-tool.md | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/exercises/JavaScript/03-add-your-first-tool.md b/exercises/JavaScript/03-add-your-first-tool.md index d90bc3b..ee736c2 100644 --- a/exercises/JavaScript/03-add-your-first-tool.md +++ b/exercises/JavaScript/03-add-your-first-tool.md @@ -312,8 +312,10 @@ import type { RPT1Payload } from "./types.js"; export class RPT1Client { private client: RptClient; - constructor() { - this.client = new RptClient({ resourceGroup: process.env.RESOURCE_GROUP! }); + constructor(modelName: 'sap-rpt-1-small' | 'sap-rpt-1-large' = 'sap-rpt-1-small') { + // Initialize the SDK client + // By default, it uses 'sap-rpt-1-small' + this.client = new RptClient(modelName); } async predictWithoutSchema(payload: RPT1Payload): Promise { @@ -326,20 +328,18 @@ export class RPT1Client { > 💡 **Understanding the wrapper class:** > > - `RptClient` from `@sap-ai-sdk/rpt` handles authentication and the API call automatically: no OAuth token fetching needed. +> - The constructor accepts a model name (`'sap-rpt-1-small'` or `'sap-rpt-1-large'`) and defaults to `'sap-rpt-1-small'`. > - `payload as any`: the `RPT1Payload` type we defined and the SDK's internal `PredictionData` type describe the same JSON structure, but TypeScript does not know that. They are two separate type definitions written independently (one by us, one by the SDK authors) so TypeScript treats them as incompatible and refuses to accept one where the other is expected. The `as any` cast tells TypeScript to stop checking the type for this one call. The JSON that reaches the API at runtime is identical either way; this is purely a compile-time compatibility issue between two type definitions. > - `Promise`: the return type is `any` because the SDK's `PredictResponsePayload` type is complex and we don't need to type it precisely here. -### Step 2: Update .env with the RPT-1 Deployment URL +### Step 2: Verify Your .env Configuration -👉 Go to [SAP AI Launchpad](https://genai-codejam-luyq1wkg.ai-launchpad.prod.eu-central-1.aws.ai-prod.cloud.sap/aic/index.html#/workspaces&/a/detail/TwoColumnsMidExpanded/?workspace=api-connection&resourceGroup=s3-grounding) +The `@sap-ai-sdk/rpt` client resolves the RPT-1 deployment by **model name** — no deployment URL is needed. The `RPT1Client` constructor accepts `'sap-rpt-1-small'` (default) or `'sap-rpt-1-large'`. -> DO NOT USE THE `default` RESOURCE GROUP! - -👉 Go to **Workspaces** → Select your workspace → resource group `ai-agents-codejam`. +👉 Make sure your `.env` file contains valid SAP AI Core credentials (`AICORE_SERVICE_KEY`) and your `RESOURCE_GROUP` is set to `ai-agents-codejam`. -👉 Navigate to `ML Operations > Deployments > sap-rpt-1-large_autogenerated` +> DO NOT USE THE `default` RESOURCE GROUP! -👉 The `@sap-ai-sdk/rpt` client uses the resource group and looks up the RPT-1 deployment automatically. No deployment URL needed in `.env`. Just make sure your `RESOURCE_GROUP` is set correctly. --- @@ -420,9 +420,33 @@ async function appraiserNode(state: AgentState): Promise> { > payload: RPT1Payload; > ``` -### Step 3: Update main.ts to Pass the Payload +### Step 3: Update buildGraph() and Pass the Payload + +Now that `payload` is part of `AgentState`, you also need to declare it as a channel in the `StateGraph` so LangGraph knows to track it. + +👉 Update the `buildGraph()` function in `basicAgent.ts` to include the `payload` channel: + +```typescript +function buildGraph() { + const workflow = new StateGraph({ + channels: { + payload: null, + suspect_names: null, + appraisal_result: null, + messages: null, + }, + }); + + workflow + .addNode("appraiser", appraiserNode) + .addEdge(START, "appraiser") + .addEdge("appraiser", END); + + return workflow.compile(); +} +``` -👉 Update `basicAgent.ts` to pass the payload as part of the initial state: +👉 Update `main()` in `basicAgent.ts` to pass the payload as part of the initial state: ```typescript const initialState: AgentState = {