@sassoftware/sas-score-mcp-serverjs 1.0.1-32 → 1.0.1-34

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.
@@ -0,0 +1,57 @@
1
+ ---
2
+ resource: "table"
3
+ description: "Decision tree for table operations. Use sas-score-sas-query for aggregation/query requests; otherwise use sas-score-read-table for raw rows."
4
+ intents:
5
+ list:
6
+ parse:
7
+ lib: "$lib"
8
+ exec:
9
+ tool: "list-tables"
10
+ args:
11
+ lib: "$lib"
12
+ start: 1
13
+ limit: 10
14
+ format: "list of tables"
15
+ find:
16
+ parse:
17
+ lib: "$lib"
18
+ name: "$name"
19
+ exec:
20
+ tool: "find-table"
21
+ args:
22
+ lib: "$lib"
23
+ name: "$name"
24
+ format: "find response"
25
+ read:
26
+ parse:
27
+ lib: "$lib"
28
+ table: "$table"
29
+ where: "$where"
30
+ aggregation_requested: "$aggregation_requested" # boolean inferred from request
31
+ aggregation_query: "$aggregation_query"
32
+ verify:
33
+ tool: "find-table"
34
+ args:
35
+ lib: "$lib"
36
+ name: "$table"
37
+ decision:
38
+ - condition: "aggregation_requested == true"
39
+ exec:
40
+ tool: "sas-score-sas-query"
41
+ args:
42
+ table: "$lib.$table"
43
+ query: "$aggregation_query"
44
+ - condition: "default"
45
+ exec:
46
+ tool: "sas-score-read-table"
47
+ args:
48
+ lib: "$lib"
49
+ table: "$table"
50
+ where: "$where"
51
+ format: "rows or aggregated result"
52
+ read_and_score:
53
+ description: "Compose read then score (read decision chooses sas-query vs read-table)."
54
+ compose:
55
+ - step: "table.read"
56
+ - step: "mas.score"
57
+ format: "rows with appended predictions"
@@ -66,7 +66,7 @@ Always verify resources exist before executing (except SCR which has no pre-chec
66
66
  |---|---|
67
67
  | Find library | sas-score-find-library |
68
68
  | Find table | sas-score-find-table |
69
- | Find model (MAS) | sas-score-find-model |
69
+ | Find model (MAS) | sas-score-find-mas |
70
70
  | Find job | sas-score-find-job |
71
71
  | Find jobdef | sas-score-find-jobdef |
72
72
  | Read table | sas-score-read-table |
@@ -14,15 +14,14 @@ If the specified resource is ambiguous, ask the user for clarification (e.g. "Ar
14
14
 
15
15
  **Model**: If user just says "model X" without specifying type, default to MAS model (this is an explicit exception to the 'never invent' rule, but it is a predefined convention in SAS).
16
16
 
17
- Verification vs Retrieval (simplified)
17
+ Verification rules
18
+ - Always verify the target resource exists using the appropriate `find-*` tool before attempting retrieval, except for SCR models (see Exceptions below).
19
+ - For tables, determine server (CAS vs SAS) during verification; if ambiguous, ask the user for the full `lib.table` or server.
20
+ - For models, strip suffixes such as `.mas`, `.job`, `.jobdef` or `.scr` before lookup to avoid lookup failures.
18
21
 
19
- - We separate the workflow into two clear, sequential phases to reduce branching and cognitive load:
20
- 1. Verification phase — confirm the resource exists and determine its exact type and server. Use the appropriate "find" tool for all resource types except SCR models.
21
- 2. Retrieval phase — after successful verification, call the detail/read tool appropriate for the identified resource type to fetch metadata or content.
22
-
23
- - Exception for SCR models: document the exception inline — SCR models may be queried directly with `sas-score-scr-info` when the user provides a specific SCR endpoint. Even when skipping verification, still validate the endpoint/URL format before calling the tool.
24
-
25
- Apply this separation consistently across MAS models, Job models, JobDef models, SCR models, and tables.
22
+ Defaults & exceptions
23
+ - Default model type: MAS when the user says `model X` without specifying a type.
24
+ - If verification fails, inform the user and ask for corrected or more specific identifiers.
26
25
 
27
26
  ---
28
27
 
@@ -98,7 +97,7 @@ sas-score-mas-info({
98
97
  ```
99
98
  User: "What inputs does mas model churnRisk need?"
100
99
 
101
- 1. Find: sas-score-find-model({ name: "churnRisk" })
100
+ 1. Find: sas-score-find-mas({ name: "churnRisk" })
102
101
  2. Get info: sas-score-mas-info({ model: "churnRisk" })
103
102
  3. Return: { inputs: [...], outputs: [...], description: "..." }
104
103
  ```
@@ -267,7 +266,7 @@ If a request fails:
267
266
  **Workflow**:
268
267
  1. Classify: MAS model detail request
269
268
  2. Verify: Find model creditScore → Found ✓
270
- 3. Execute: `sas-score-model-info({ model: "creditScore" })`
269
+ 3. Execute: `sas-score-mas-info({ model: "creditScore" })`
271
270
  4. Return: Model inputs, outputs, and description
272
271
 
273
272
  ### Example 2: SCR Model Schema
@@ -9,6 +9,12 @@ description: >
9
9
 
10
10
  Use this strategy to verify that a resource exists before executing any action.
11
11
 
12
+ Verification rules
13
+ - Use `find-*` tools to confirm resource existence; do not use `list-*` tools for verification.
14
+ - For tables, determine server (CAS vs SAS) from the library; if unknown, try CAS first then SAS (uppercase lib for SAS).
15
+ - For models with no explicit type, default to MAS unless the user specifies otherwise.
16
+ - SCR models require a URL/endpoint; ask the user for the endpoint rather than attempting a find.
17
+
12
18
  Do **not** use list tools for verifying or finding specific resources. List tools are for discovery and exploration only, not for confirming the existence of a specific resource.
13
19
 
14
20
  ## Resource Types and Find Tools
@@ -66,7 +72,7 @@ Do **not** use list tools for verifying or finding specific resources. List tool
66
72
 
67
73
  ### 3. Find Scoring Model
68
74
 
69
- **Trigger**: "find model X", "find mas model X", "find job model X", "find jobdef model X",
75
+ **Trigger**: "find model X.mas", "find mas model X", "find job model X", "find jobdef model X",
70
76
  "find scr model X", "does model X exist", "locate model X", "find job X", "does job X exist",
71
77
  "find jobdef X", "does jobdef X exist"
72
78
 
@@ -74,19 +80,19 @@ Do **not** use list tools for verifying or finding specific resources. List tool
74
80
 
75
81
  | User phrase / suffix | Model type | Find Tool |
76
82
  |------------------------------------------------|------------|------------------------|
77
- | `find mas model X` / `X.mas` / `mas X` | MAS | `sas-score-find-model` |
83
+ | `find mas model X` / `X.mas` / `mas X` | MAS | `sas-score-find-mas` |
78
84
  | `find job model X` / `X.job` / `job X` | Job | `sas-score-find-job` |
79
85
  | `find jobdef model X` / `X.jobdef` / `jobdef X`| JobDef | `sas-score-find-jobdef`|
80
86
  | `find scr model X` / `X.scr` / `scr X` | SCR | *(no tool — ask for URL)*|
81
- | `find model X` (no type) | MAS (default) | `sas-score-find-model` |
87
+
82
88
 
83
89
  #### MAS Model
84
90
 
85
- **Tool**: `sas-score-find-model`
91
+ **Tool**: `sas-score-find-mas`
86
92
 
87
93
  **Logic**: Strip `.mas` suffix if present, use base name.
88
94
  ```
89
- sas-score-find-model({ name: "<model>" })
95
+ sas-score-find-mas({ name: "<model>" })
90
96
  ```
91
97
 
92
98
  #### Job Model
@@ -123,11 +129,11 @@ If user says "find model X" without a type qualifier, infer the type from the su
123
129
 
124
130
  | Pattern | Type | Find Tool |
125
131
  |--------------------------------------|---------|-------------------------|
126
- | `X.mas` / `mas model X` / `mas X` | MAS | `sas-score-find-model` |
132
+ | `X.mas` / `mas model X` / `mas X` | MAS | `sas-score-find-mas` |
127
133
  | `X.job` / `job model X` / `job X` | Job | `sas-score-find-job` |
128
134
  | `X.jobdef` / `jobdef model X` / `jobdef X` | JobDef | `sas-score-find-jobdef` |
129
135
  | `X.scr` / `scr model X` / `scr X` | SCR | Skip (no find tool) |
130
- | (none) | Default to MAS | `sas-score-find-model` |
136
+ | (none) | Default to MAS | `sas-score-find-mas` |
131
137
 
132
138
  ---
133
139
 
@@ -8,8 +8,15 @@ description: >
8
8
  # Unified Resource Listing Strategy
9
9
 
10
10
 
11
+
11
12
  Use this strategy to list available resources (libraries, tables, models, jobs, jobdefs).
12
13
 
14
+ Listing rules
15
+ - Use `list-*` tools for discovery and browsing only; do not use `list-*` to verify a specific resource's existence.
16
+ - If the user specifies a server, list from that server; otherwise list from all servers when appropriate.
17
+ - When a library is ambiguous for table listing, attempt both CAS and SAS and label results by server, or ask the user to clarify.
18
+
19
+
13
20
  ## Resource Type to Tool Mapping
14
21
 
15
22
  | Resource Type | Aliases / Adjective Form | List Tool |
@@ -8,6 +8,11 @@ description: >
8
8
 
9
9
  Use this strategy when the user requests to read, fetch, or query data from a table.
10
10
 
11
+ Rules summary
12
+ - Verification rules: verify the table exists using `find-*` and determine the server (CAS vs SAS); ask the user if ambiguous. Do not assume a default server unless explicitly instructed.
13
+ - Execution rules: choose `sas-score-read-table` for raw row reads and `sas-score-sas-query` for aggregations/joins/groupings; if intent is ambiguous, ask the user.
14
+ - Error handling: surface clear guidance when table or column names are missing or misspelled.
15
+
11
16
  ## Prerequisites
12
17
 
13
18
  Before reading:
@@ -100,7 +105,7 @@ If the user's intent is ambiguous or mixes aggregation and raw reads, ask the us
100
105
 
101
106
  ## Table Name Format
102
107
 
103
- - **CAS tables**: `Caslib.table` or `Public.customers` (lowercase caslib, mixed case table)
108
+ - **CAS tables**: `Caslib.table` or `Public.customers` (mixed case table)
104
109
  - **SAS tables**: `LIBREF.table` or `SASHELP.cars` (uppercase libref, case-insensitive table)
105
110
 
106
111
  ---
@@ -1,108 +1,82 @@
1
1
  ---
2
2
  name: request-routing
3
3
  description: >
4
- Universal routing strategy for all SAS Viya requests. Every request follows the same three-step workflow.
4
+ Canonical, compact request-routing strategy for SAS Viya requests.
5
5
  ---
6
6
 
7
- # Universal Request Routing Strategy
8
-
9
- All SAS Viya requests follow this three-step workflow:
10
-
11
- ## Step 1: Verify Resources Exist
12
-
13
- Before executing any action, verify that the target resources exist.
14
-
15
- | Resource Type | Find Tool | Notes |
16
- |---|---|---|
17
- | Library | `sas-score-find-library` | For tables, if server is not specified (cas or sas), determine server here. Other resource types do not require server specification. |
18
- | Table | `sas-score-find-table` | Requires library name and server. |
19
- | MAS Model | `sas-score-find-model` | No server selection. |
20
- | Job | `sas-score-find-job` | No server selection. |
21
- | JobDef | `sas-score-find-jobdef` | No server selection. |
22
- | SCR Model | Skip verification | SCR models do not require pre-verification. |
23
-
24
- **Rule**: Always verify before executing. Exception: SCR models can be scored directly.
25
-
26
- ---
27
-
28
- ## Step 2: Execute the Request
29
-
30
- Once resources are verified to exist, select the appropriate execution tool:
31
-
32
- | Request Type | Tool | Input |
33
- |---|---|---|
34
- | Read table rows | `sas-score-read-table` | lib, table, server (from Step 1) |
35
- | Query table (aggregation) | `sas-score-sas-query` | lib.table, SQL query |
36
- | Score with MAS model / `mas model X` | `sas-score-mas-score` | model name, scenario data |
37
- | Score with Job model / `job model X` | `sas-score-run-job` | job name, scenario parameters |
38
- | Score with JobDef model / `jobdef model X` | `sas-score-run-jobdef` | jobdef name, scenario parameters |
39
- | Score with SCR model / `scr model X` | `sas-score-scr-score` | SCR URL, scenario data |
40
- | Describe MAS model / `mas model X` | `sas-score-mas-info` | model name |
41
- | Describe Job model / `job model X` | `sas-score-job-info` | job name |
42
- | Describe JobDef model / `jobdef model X` | `sas-score-jobdef-info` | jobdef name |
43
- | Describe SCR model / `scr model X` | `sas-score-scr-info` | SCR URL |
44
- | Describe table | `sas-score-table-info` | lib, table, server |
45
-
46
- ---
47
-
48
- ## Step 3: Merge Results
49
-
50
- Combine verification and execution results:
51
-
52
- - For **read/query**: Return rows as-is.
53
- - For **scoring**: Merge predictions with input scenario data.
54
- - For **jobs/jobdefs**: Return execution results (tables, logs).
55
-
7
+ # Request Routing — Canonical SKILL
8
+
9
+ Purpose: single source-of-truth for routing SAS Viya actions (read, query, score, describe, list).
10
+
11
+ Quick workflow
12
+ - Verify — confirm resources exist (use find-*).
13
+ - Execute run the mapped execution tool (read, query, score, describe, list).
14
+ - Format — return results and append a short Strategy Summary.
15
+
16
+ **Important Reminder**: If the category is "Find resource" do not use the list-* rules below, use the specific find-* tool for that resource type. The list-* tools are for discovery when the user does not have a specific resource in mind.
17
+
18
+ Classification
19
+ | Category | Triggers | Primary Action | Primary Tool(s) |
20
+ |---|---|---|---|
21
+ | Find resource | "find", "does X exist", "locate", "verify" | Verify resource | `sas-score-find-library`, `sas-score-find-table`, `sas-score-find-mas`, `sas-score-find-job`, `sas-score-find-jobdef` |
22
+ | Read / Query | "read", "show rows", "how many", "count", "average", "query" | Read / aggregate | `sas-score-read-table`, `sas-score-sas-query` |
23
+ | Score | "score", "predict", "run model" | Score inputs | `sas-score-mas-score`, `sas-score-run-job`, `sas-score-run-jobdef`, `sas-score-scr-score` |
24
+ | List / Discover | "list", "show all", "browse" | List resources | `list-*` tools (e.g., `list-mas`, `list-jobs`) |
25
+ | Describe | "describe", "what inputs", "metadata" | Return metadata | `sas-score-*-info` (mas/job/jobdef/scr), `sas-score-table-info` |
26
+
27
+ Verification rules
28
+ - Always verify resources using the appropriate `find-*` tool before executing actions
29
+
30
+ Execution rules
31
+ - Execute only after verification; choose the execution tool per the Execute mapping section.
32
+ - Scoring flows:
33
+ - Inline scenario: verify model → call scoring tool.
34
+ - Table rows: verify model + table → read rows map columns to model inputs score merge predictions with rows.
35
+ - Read/query flows:
36
+ - Use `sas-score-sas-query` for aggregations and groupings.
37
+ - Use `sas-score-read-table` for row reads.
38
+ - When mapping between table columns and model inputs is ambiguous, ask the user for explicit mapping.
39
+
40
+ Defaults & exceptions
41
+ - Default model type: MAS unless the user specifies otherwise.
42
+ - Skip `find-*` verification for SCR models; SCR endpoints may be scored directly.
43
+ - If server determination is ambiguous, prompt the user for clarification.
44
+
45
+ Execute mapping (concise)
46
+ - Read rows: `sas-score-read-table` (lib, table, server)
47
+ - Aggregation/query: `sas-score-sas-query` (lib.table, query)
48
+ - MAS scoring: `sas-score-mas-score` (mas, scenario)
49
+ - Job scoring: `sas-score-run-job` (job, scenario)
50
+ - JobDef scoring: `sas-score-run-jobdef` (jobdef, scenario)
51
+ - SCR scoring: `sas-score-scr-score` (url, scenario)
52
+ - Describe: `sas-score-*-info`, `sas-score-table-info`
53
+
54
+ Combined Read + Score (short)
55
+ 1. Verify: find table (server) and find the model (mas,job,jobdef,scr). If table/model not found, ask user to clarify resource and server.
56
+ 2. Read: fetch rows (read-table or sas-query).
57
+ 3. Map: ensure table columns match model inputs; ask for mapping if needed.
58
+ 4. Score: call the appropriate scoring tool.
59
+ 5. Merge: attach predictions to rows and return.
60
+
61
+ Strategy Summary (append to responses)
56
62
  ---
57
-
58
-
59
- ## Special Case: Read + Score (Combined Workflow)
60
-
61
- When the user requests scoring records from a table, follow these sub-workflows in order:
62
-
63
- 1. **Verify**
64
- - Find the table (determine server as described above)
65
- - Find the model
66
- 2. **Read**
67
- - Fetch rows from the table using `sas-score-read-table` or `sas-score-sas-query`
68
- 3. **Map**
69
- - Check if table columns match model input variables
70
- - If not, ask user for mapping
71
- 4. **Score**
72
- - Score each row using `sas-score-mas-score` (for MAS) or `sas-score-scr-score` (for SCR)
73
- 5. **Merge**
74
- - Combine predictions with original rows
75
-
76
- ---
77
-
78
- ## Error Handling
79
-
80
- | Error | Action |
81
- |---|---|
82
- | Resource not found | Ask user to verify name and server (for tables). |
83
- | Column/input mismatch | Ask user to map table columns to model inputs. |
84
- | Empty result | Ask whether to adjust filter/criteria. |
85
-
63
+ **Strategy Summary:**
64
+ - Classification: [Find / Read / Score / List / Describe]
65
+ - Verification: [Resources verified / skipped]
66
+ - Tool(s): [Primary tool(s) invoked]
67
+ - Decision: [Server chosen, model type, mapping]
68
+ - Next steps: [Follow-ups or clarifications]
86
69
  ---
87
70
 
88
- ## Examples
89
-
90
- ### Example 1: Read a table
91
- **Request**: "read customers in Public"
92
- 1. Find library Public Verified (CAS)
93
- 2. Read table customers in Public (CAS)
94
- 3. Return rows
71
+ Error handling (short)
72
+ - Resource not found → ask for exact resource name and server (for tables).
73
+ - Column/input mismatch request mapping from user.
74
+ - Empty result ask to relax filters or confirm criteria.
75
+ - Execution errorreturn tool error verbatim.
95
76
 
96
- ### Example 2: Score with inline scenario
97
- **Request**: "score a=1, b=2 with model simplejob.job"
98
- 1. Find job simplejob → Verified
99
- 2. Run simplejob with scenario {a: 1, b: 2}
100
- 3. Return result
77
+ Examples (minimal)
78
+ - Read: "read customers in Public" find Public (CAS) → read-table → return rows.
79
+ - Score inline: "score a=1,b=2 with job simplejob"find job → run-job → return merged result.
80
+ - Score table: "score Public.customers with model risk" find table (CAS) & model (MAS) → read rows → score → return merged.
101
81
 
102
- ### Example 3: Score records from table
103
- **Request**: "score records from Public.customers with model risk_model.mas"
104
- 1. Find table customers in Public → Verified (CAS)
105
- 2. Find model risk_model → Verified (MAS)
106
- 3. Read rows from Public.customers
107
- 4. Score each row with risk_model
108
- 5. Return merged predictions + original data
82
+ Notes: Keep this SKILL as the canonical, compact router; agent wrappers should be short and reference this document for details and examples.
@@ -11,6 +11,11 @@ description: >
11
11
 
12
12
  Use this strategy when the user requests model scoring, predictions, or running jobs/jobdefs.
13
13
 
14
+ Rules summary
15
+ - Verification rules: always verify model existence with `find-*` (except SCR); for table scoring verify both model and table and determine server.
16
+ - Execution rules: inline scenarios → verify model → score; table rows → verify table → read → score (batch). Ask for column-to-input mapping when needed.
17
+ - Defaults & exceptions: default model type to MAS when unspecified; skip pre-verification for SCR models and require a valid SCR endpoint.
18
+
14
19
  ## Prerequisites
15
20
 
16
21
  1. Verify the model/job exists using find-resources skill
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sassoftware/sas-score-mcp-serverjs",
3
- "version": "1.0.1-32",
3
+ "version": "1.0.1-34",
4
4
  "description": "A mcp server for SAS Viya",
5
5
  "author": "Deva Kumar <deva.kumar@sas.com>",
6
6
  "license": "Apache-2.0",
@@ -1,49 +1,49 @@
1
- import matplotlib
2
- matplotlib.use('Agg')
3
- import matplotlib.pyplot as plt
4
- from pathlib import Path
5
-
6
- data = [
7
- ("Cadillac", 50474.375),
8
- ("Hummer", 49995.0),
9
- ("Lincoln", 42875.555556),
10
- ("Buick", 30537.777778),
11
- ("GMC", 29560.5),
12
- ("Mercury", 27972.777778),
13
- ("Chrysler", 27252.0),
14
- ("Chevrolet", 26587.037037),
15
- ("Dodge", 26253.846154),
16
- ("Jeep", 24518.333333),
17
- ("Pontiac", 24156.363636),
18
- ("Ford", 24015.869565),
19
- ("Oldsmobile", 23763.333333),
20
- ("Saturn", 17234.375),
21
- ]
22
-
23
- # Sort by value descending
24
- data.sort(key=lambda x: x[1], reverse=True)
25
- makes = [d[0] for d in data]
26
- values = [d[1] for d in data]
27
-
28
- out_dir = Path('outputs')
29
- out_dir.mkdir(parents=True, exist_ok=True)
30
- out_file = out_dir / 'make_avg_msrp_usa.png'
31
-
32
- plt.figure(figsize=(12, 6))
33
- bars = plt.bar(makes, values, color='tab:blue')
34
- plt.title('Average MSRP by Make (Origin = USA)')
35
- plt.ylabel('Average MSRP')
36
- plt.xticks(rotation=45, ha='right')
37
- plt.tight_layout()
38
-
39
- # Annotate bars
40
- for bar in bars:
41
- height = bar.get_height()
42
- plt.annotate(f'{height:,.0f}',
43
- xy=(bar.get_x() + bar.get_width() / 2, height),
44
- xytext=(0, 3),
45
- textcoords='offset points',
46
- ha='center', va='bottom', fontsize=8)
47
-
48
- plt.savefig(out_file)
49
- print(f'Plot saved to {out_file}')
1
+ import matplotlib
2
+ matplotlib.use('Agg')
3
+ import matplotlib.pyplot as plt
4
+ from pathlib import Path
5
+
6
+ data = [
7
+ ("Cadillac", 50474.375),
8
+ ("Hummer", 49995.0),
9
+ ("Lincoln", 42875.555556),
10
+ ("Buick", 30537.777778),
11
+ ("GMC", 29560.5),
12
+ ("Mercury", 27972.777778),
13
+ ("Chrysler", 27252.0),
14
+ ("Chevrolet", 26587.037037),
15
+ ("Dodge", 26253.846154),
16
+ ("Jeep", 24518.333333),
17
+ ("Pontiac", 24156.363636),
18
+ ("Ford", 24015.869565),
19
+ ("Oldsmobile", 23763.333333),
20
+ ("Saturn", 17234.375),
21
+ ]
22
+
23
+ # Sort by value descending
24
+ data.sort(key=lambda x: x[1], reverse=True)
25
+ makes = [d[0] for d in data]
26
+ values = [d[1] for d in data]
27
+
28
+ out_dir = Path('outputs')
29
+ out_dir.mkdir(parents=True, exist_ok=True)
30
+ out_file = out_dir / 'make_avg_msrp_usa.png'
31
+
32
+ plt.figure(figsize=(12, 6))
33
+ bars = plt.bar(makes, values, color='tab:blue')
34
+ plt.title('Average MSRP by Make (Origin = USA)')
35
+ plt.ylabel('Average MSRP')
36
+ plt.xticks(rotation=45, ha='right')
37
+ plt.tight_layout()
38
+
39
+ # Annotate bars
40
+ for bar in bars:
41
+ height = bar.get_height()
42
+ plt.annotate(f'{height:,.0f}',
43
+ xy=(bar.get_x() + bar.get_width() / 2, height),
44
+ xytext=(0, 3),
45
+ textcoords='offset points',
46
+ ha='center', va='bottom', fontsize=8)
47
+
48
+ plt.savefig(out_file)
49
+ print(f'Plot saved to {out_file}')
@@ -1,12 +1,12 @@
1
- /*
2
- * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
-
6
- import _listMas from './_listMas.js';
7
- async function _findMas(params) {
8
- let r = await _listMas(params);
9
- console.log ("findMas result:" , r);
10
- return r;
11
- }
1
+ /*
2
+ * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import _listMas from './_listMas.js';
7
+ async function _findMas(params) {
8
+ let r = await _listMas(params);
9
+ console.log ("findMas result:" , r);
10
+ return r;
11
+ }
12
12
  export default _findMas;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ import axios from 'axios';
7
+
8
+ async function _findScr(params) {
9
+ let {url} = params;
10
+ let config = {
11
+ method: 'HEAD',
12
+ url: url + '/apiMeta/api',
13
+ headers: {
14
+ 'Accept': 'application/json'
15
+ }
16
+ }
17
+ try {
18
+ console.error('[Note] Config:', config);
19
+ let response = await axios(config);
20
+ console.error('[Note] Response status:', response.status);
21
+ if (response.status !== 200) {
22
+ return {isError: true, content: [{ type: 'text', text: `SCR model ${url} not found` }]};
23
+ } else if (response.status === 200) {
24
+ return { content: [{ type: 'text', text: `Model ${url} is available` }]};
25
+ }
26
+ }
27
+ catch (error) {
28
+ return {isError: true,content: [{ type: 'text', text: JSON.stringify(error) }]};
29
+ }
30
+ }
31
+ export default _findScr;
@@ -5,12 +5,12 @@
5
5
  import { z } from 'zod';
6
6
 
7
7
  function devaScore(_appContext) {
8
-
8
+ let brand = _appContext.brand + '-';
9
9
  let description = `
10
10
  deva-score — compute a numeric score based on two input values.
11
11
 
12
12
  USE when: calculate deva score, score these values, compute score for numbers
13
- DO NOT USE for: model scoring (use model-score), statistical calculations, data lookup
13
+ DO NOT USE for: model scoring (use ${brand}model-score), statistical calculations, data lookup
14
14
 
15
15
  PARAMETERS
16
16
  - a: number (required) — first input value
@@ -30,9 +30,9 @@ EXAMPLES
30
30
  - "Deva score 20 and 30" → { a: 20, b: 30 } returns 2100
31
31
 
32
32
  NEGATIVE EXAMPLES (do not route here)
33
- - "Score this customer with credit model" (use model-score)
34
- - "Calculate the mean of these values" (use run-sas-program or sas-query)
35
- - "Statistical analysis of numbers" (use sas-query)
33
+ - "Score this customer with credit model" (use ${brand}model-score)
34
+ - "Calculate the mean of these values" (use ${brand}run-sas-program or ${brand}sas-query)
35
+ - "Statistical analysis of numbers" (use ${brand}sas-query)
36
36
 
37
37
  RESPONSE
38
38
  Returns { score: (a + b) * 42 }
@@ -11,19 +11,22 @@ function findJob(_appContext) {
11
11
  find-job — locate a specific SAS Viya job.
12
12
 
13
13
  USE when: find job, does job exist, is there a job named, lookup job, verify job exists
14
- DO NOT USE for: list jobs (use list-jobs), run job (use run-job), execute jobdef (use run-jobdef), find lib/table/model (use respective tools)
14
+ DO NOT USE for: list jobs (use ${_appContext.brand}-list-jobs), run job (use ${_appContext.brand}-run-job), execute jobdef (use ${_appContext.brand}-run-jobdef), find lib/table/model (use respective tools)
15
15
 
16
16
  PARAMETERS
17
17
  - name: string (required) — job name to locate; if multiple supplied, use first
18
18
 
19
+ Naming Rules:
20
+ - If user provides name with "job" suffix ".job", strip the suffix (e.g., "cars_job_v4.job"), and look for "cars_job_v4".
21
+
19
22
  ROUTING RULES
20
23
  - "find job <name>" → { name: "<name>" }
21
24
  - "does job <name> exist" → { name: "<name>" }
22
25
  - "is there a job named <name>" → { name: "<name>" }
23
26
  - "lookup/verify job <name>" → { name: "<name>" }
24
27
  - "find job" with no name → ask "Which job name would you like to find?"
25
- - "find all jobs / list jobs" → use list-jobs instead
26
- - "run job <name>" → use run-job instead
28
+ - "find all jobs / list jobs" → use ${_appContext.brand}-list-jobs instead
29
+ - "run job <name>" → use ${_appContext.brand}-run-job instead
27
30
 
28
31
  EXAMPLES
29
32
  - "find job cars_job_v4" → { name: "cars_job_v4" }
@@ -31,9 +34,9 @@ EXAMPLES
31
34
  - "is there a job named metricsRefresh" → { name: "metricsRefresh" }
32
35
 
33
36
  NEGATIVE EXAMPLES (do not route here)
34
- - "list jobs" (use list-jobs)
35
- - "run job cars_job_v4" (use run-job)
36
- - "execute jobdef cars_job_v4" (use run-jobdef)
37
+ - "list jobs" (use ${_appContext.brand}-list-jobs)
38
+ - "run job cars_job_v4" (use ${_appContext.brand}-run-job)
39
+ - "execute jobdef cars_job_v4" (use ${_appContext.brand}-run-jobdef)
37
40
 
38
41
  ERRORS
39
42
  Returns { jobs: [] } if not found; { jobs: [name, ...] } if found. Never hallucinate job names.