@sassoftware/sas-score-mcp-serverjs 1.0.1-8 → 1.1.1
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.
- package/.skills/.claude-plugin/plugin.json +59 -0
- package/.skills/agents/sas-score-mcp-serverjs-agent.md +26 -0
- package/.skills/copilot-instructions.md +62 -0
- package/.skills/skills/README.md +204 -0
- package/.skills/skills/detail-strategy/SKILL.md +316 -0
- package/.skills/skills/find-library-server/SKILL.md +62 -0
- package/.skills/skills/find-resources/SKILL.md +66 -0
- package/.skills/skills/list-library/SKILL.md +30 -0
- package/.skills/skills/list-mas-job-jobdef/SKILL.md +31 -0
- package/.skills/skills/list-tables/SKILL.md +30 -0
- package/.skills/skills/read-strategy/SKILL.md +87 -0
- package/.skills/skills/request-routing/SKILL.md +112 -0
- package/.skills/skills/score-cas/SKILL.md +95 -0
- package/.skills/skills/score-job-jobdef/SKILL.md +58 -0
- package/.skills/skills/score-mas-scr/SKILL.md +58 -0
- package/.skills/skills/score-program/SKILL.md +59 -0
- package/.skills/skills/score-strategy/SKILL.md +39 -0
- package/README.md +96 -54
- package/cli.js +29 -38
- package/openApi.yaml +121 -121
- package/package.json +15 -13
- package/scripts/docs/SCORE_SKILL_REFERENCE.md +17 -16
- package/scripts/docs/TOOL_DESCRIPTION_TEMPLATE.md +3 -3
- package/scripts/docs/TOOL_UPDATES_SUMMARY.md +65 -63
- package/scripts/docs/oauth-http-transport.md +2 -2
- package/scripts/docs/sas-mcp-tools-reference.md +43 -32
- package/scripts/plot_msrp_usa.py +49 -0
- package/scripts/refreshtoken.js +58 -0
- package/scripts/runListScr.mjs +16 -0
- package/src/createMcpServer.js +4 -1
- package/src/expressMcpServer.js +47 -49
- package/src/oauthHandlers/authorize.js +4 -1
- package/src/oauthHandlers/baseUrl.js +4 -0
- package/src/oauthHandlers/callback.js +4 -0
- package/src/oauthHandlers/getMetadata.js +4 -0
- package/src/oauthHandlers/index.js +4 -0
- package/src/oauthHandlers/token.js +4 -0
- package/src/openApi.yaml +121 -121
- package/src/processHeaders.js +10 -7
- package/src/setupSkills.js +6 -9
- package/src/toolHelpers/_casScore.js +32 -0
- package/src/toolHelpers/_desc.js +14 -0
- package/src/toolHelpers/_findJob.js +12 -0
- package/src/toolHelpers/_findJobdef.js +10 -0
- package/src/toolHelpers/_findLibrary.js +11 -0
- package/src/toolHelpers/_findMas.js +13 -0
- package/src/toolHelpers/_findScr.js +36 -0
- package/src/toolHelpers/_findTable.js +11 -0
- package/src/toolHelpers/_listJobdefs.js +12 -2
- package/src/toolHelpers/_listJobs.js +19 -8
- package/src/toolHelpers/{_listModels.js → _listMas.js} +4 -4
- package/src/toolHelpers/_listScr.js +13 -0
- package/src/toolHelpers/{_scrInfo.js → _scrDescribe.js} +4 -4
- package/src/toolHelpers/_scrScore.js +2 -2
- package/src/toolHelpers/_submitCasl.js +19 -17
- package/src/toolHelpers/{_tableInfo.js → _tableDescribe.js} +2 -2
- package/src/toolHelpers/getLogonPayload.js +2 -2
- package/src/toolSet/casModelScore.js +93 -0
- package/src/toolSet/casProgramScore.js +105 -0
- package/src/toolSet/devaScore.js +11 -6
- package/src/toolSet/findJob.js +74 -59
- package/src/toolSet/findJobdef.js +67 -64
- package/src/toolSet/findLibrary.js +28 -23
- package/src/toolSet/findMas.js +72 -0
- package/src/toolSet/findScr.js +69 -0
- package/src/toolSet/findTable.js +34 -27
- package/src/toolSet/getEnv.js +57 -57
- package/src/toolSet/jobDescribe.js +65 -0
- package/src/toolSet/jobScore.js +90 -0
- package/src/toolSet/jobdefDescribe.js +67 -0
- package/src/toolSet/jobdefScore.js +85 -0
- package/src/toolSet/listJobdefs.js +17 -8
- package/src/toolSet/listJobs.js +15 -8
- package/src/toolSet/listLibraries.js +16 -10
- package/src/toolSet/listMas.js +71 -0
- package/src/toolSet/listScr.js +62 -0
- package/src/toolSet/listTables.js +78 -66
- package/src/toolSet/{runMacro.js → macroScore.js} +86 -82
- package/src/toolSet/makeTools.js +39 -25
- package/src/toolSet/masDescribe.js +67 -0
- package/src/toolSet/masScore.js +95 -0
- package/src/toolSet/{runProgram.js → programScore.js} +96 -93
- package/src/toolSet/readTable.js +43 -26
- package/src/toolSet/sasQuery.js +24 -18
- package/src/toolSet/scrDescribe.js +55 -0
- package/src/toolSet/scrScore.js +63 -70
- package/src/toolSet/searchAssets.js +1 -1
- package/src/toolSet/setContext.js +8 -3
- package/src/toolSet/superstat.js +61 -61
- package/src/toolSet/tableDescribe.js +65 -0
- package/.skills/sas-find-library-smart/SKILL.md +0 -155
- package/.skills/sas-find-resource-strategy/SKILL.md +0 -105
- package/.skills/sas-list-resource-strategy/SKILL.md +0 -124
- package/.skills/sas-list-tables-smart/SKILL.md +0 -128
- package/.skills/sas-read-and-score-strategy/SKILL.md +0 -113
- package/.skills/sas-read-strategy/SKILL.md +0 -154
- package/.skills/sas-request-classifier/SKILL.md +0 -74
- package/.skills/sas-score-workflow-strategy/SKILL.md +0 -314
- package/.skills_claude/CLAUDE.md +0 -201
- package/.skills_claude/agents/sas-score-mcp-serverjs-agent.md +0 -58
- package/.skills_claude/enforce-find-resource-strategy.md +0 -35
- package/.skills_github/agents/sas-score-mcp-serverjs-agent.md +0 -58
- package/.skills_github/copilot-instructions.md +0 -201
- package/.skills_github/enforce-find-resource-strategy.md +0 -35
- package/scripts/optimize_final.py +0 -140
- package/scripts/optimize_tools.py +0 -99
- package/scripts/setup-skills.js +0 -34
- package/scripts/update_descriptions.py +0 -46
- package/src/authpkce.js +0 -219
- package/src/handleGetDelete.js +0 -34
- package/src/handleRequest.js +0 -112
- package/src/hapiMcpServer.js +0 -241
- package/src/toolSet/findModel.js +0 -60
- package/src/toolSet/listModels.js +0 -56
- package/src/toolSet/modelInfo.js +0 -55
- package/src/toolSet/modelScore.js +0 -89
- package/src/toolSet/runCasProgram.js +0 -98
- package/src/toolSet/runJob.js +0 -81
- package/src/toolSet/runJobdef.js +0 -82
- package/src/toolSet/scrInfo.js +0 -52
- package/src/toolSet/tableInfo.js +0 -58
package/src/toolSet/readTable.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { z } from 'zod';
|
|
@@ -7,36 +7,52 @@ import debug from 'debug';
|
|
|
7
7
|
|
|
8
8
|
import _readTable from '../toolHelpers/_readTable.js';
|
|
9
9
|
function readTable(_appContext) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const isAgent = _appContext && _appContext.agent;
|
|
11
|
+
|
|
12
|
+
let describe = isAgent ? `
|
|
13
|
+
read-table — read rows from a CAS or SAS table.
|
|
14
|
+
PARAMS: lib (string, required), table (string, required), server ('cas'|'sas', required), where (string, optional filter), start (number, default 1), limit (number, default 10)
|
|
15
|
+
RETURNS: array of row objects
|
|
16
|
+
` : `
|
|
17
|
+
read-table - retrieve rows from a table in a CAS or SAS library.
|
|
13
18
|
|
|
14
19
|
USE when: read table, show rows, read from library, filtered data with WHERE
|
|
15
|
-
DO NOT USE for: list tables, table structure (use table-
|
|
20
|
+
DO NOT USE for: list tables, table structure (use table-describe), SQL queries (use sas-query), SAS programs
|
|
16
21
|
|
|
17
22
|
PARAMETERS
|
|
18
|
-
- table: string
|
|
19
|
-
- lib: string
|
|
20
|
-
- server: string (default: 'cas')
|
|
21
|
-
- start: number (default: 1)
|
|
22
|
-
- limit: number (default: 10)
|
|
23
|
-
- where: string
|
|
24
|
-
- format: boolean (default: true)
|
|
23
|
+
- table: string — table name (required)
|
|
24
|
+
- lib: string — caslib or libref (required)
|
|
25
|
+
- server: string (default: 'cas') — 'cas' or 'sas'
|
|
26
|
+
- start: number (default: 1) — 1-based row index
|
|
27
|
+
- limit: number (default: 10) — max rows (1-1000)
|
|
28
|
+
- where: string — SQL WHERE clause filter
|
|
29
|
+
- format: boolean (default: true) — formatted or raw values
|
|
30
|
+
|
|
31
|
+
PARSING ROWS FROM USER INPUT
|
|
32
|
+
"first N rows/records" → start: 1, limit: N ("first" = count from beginning, never an offset)
|
|
33
|
+
"top N rows" → start: 1, limit: N
|
|
34
|
+
"N rows" / "N records" → start: 1, limit: N
|
|
35
|
+
"read N rows from lib.table" → lib: "lib", table: "table", start: 1, limit: N
|
|
36
|
+
"rows N to M" → start: N, limit: M-N+1
|
|
37
|
+
"starting from row N" → start: N, limit: 10 (default)
|
|
38
|
+
(no count specified) → start: 1, limit: 10 (default)
|
|
39
|
+
|
|
40
|
+
DOTTED FORMAT: "lib.table" → lib: "lib", table: "table" (split on first dot)
|
|
25
41
|
|
|
26
42
|
ROUTING RULES
|
|
27
|
-
- "read table cars in Samples"
|
|
28
|
-
- "show 25 rows from customers"
|
|
29
|
-
- "read from mylib.orders where status='shipped'"
|
|
43
|
+
- "read table cars in Samples" → { table: "cars", lib: "Samples", start: 1, limit: 10 }
|
|
44
|
+
- "show 25 rows from customers" → { table: "customers", lib: "<lib>", limit: 25, start: 1 }
|
|
45
|
+
- "read from mylib.orders where status='shipped'" → { table: "orders", lib: "mylib", where: "status='shipped'", start: 1, limit: 10 }
|
|
30
46
|
|
|
31
47
|
EXAMPLES
|
|
32
|
-
- "read table cars in Samples"
|
|
33
|
-
- "show 25 rows from customers"
|
|
48
|
+
- "read table cars in Samples" → { table: "cars", lib: "Samples", start: 1, limit: 10 }
|
|
49
|
+
- "show 25 rows from customers" → { table: "customers", lib: "mylib", limit: 25, start: 1 }
|
|
34
50
|
|
|
35
51
|
NEGATIVE EXAMPLES (do not route here)
|
|
36
52
|
- "list tables in Samples" (use list-tables)
|
|
37
|
-
- "what columns are in cars" (use table-
|
|
53
|
+
- "what columns are in cars" (use table-describe)
|
|
38
54
|
- "execute SQL query" (use sas-query)
|
|
39
|
-
- "run SAS code" (use
|
|
55
|
+
- "run SAS code" (use program-score)
|
|
40
56
|
|
|
41
57
|
ERRORS
|
|
42
58
|
Returns rows array, total count, filtered_count, columns metadata. Empty array if no matches.
|
|
@@ -46,12 +62,12 @@ Returns rows array, total count, filtered_count, columns metadata. Empty array i
|
|
|
46
62
|
name: 'read-table',
|
|
47
63
|
description: describe,
|
|
48
64
|
inputSchema: z.object({
|
|
49
|
-
table: z.string(),
|
|
50
|
-
lib: z.string().optional(),
|
|
51
|
-
start: z.number().optional(),
|
|
52
|
-
limit: z.number().optional(),
|
|
53
|
-
server: z.
|
|
54
|
-
where: z.string().optional()
|
|
65
|
+
table: z.string().min(1),
|
|
66
|
+
lib: z.string().min(1).optional(),
|
|
67
|
+
start: z.number().int().min(1).optional(),
|
|
68
|
+
limit: z.number().int().min(1).max(1000).optional(),
|
|
69
|
+
server: z.enum(['cas', 'sas']).optional(),
|
|
70
|
+
where: z.string().min(1).optional()
|
|
55
71
|
}),
|
|
56
72
|
handler: async (params) => {
|
|
57
73
|
let r = await _readTable(params,'query');
|
|
@@ -61,3 +77,4 @@ Returns rows array, total count, filtered_count, columns metadata. Empty array i
|
|
|
61
77
|
return specs;
|
|
62
78
|
}
|
|
63
79
|
export default readTable;
|
|
80
|
+
|
package/src/toolSet/sasQuery.js
CHANGED
|
@@ -1,38 +1,43 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import {z} from 'zod';
|
|
6
6
|
import _jobSubmit from '../toolHelpers/_jobSubmit.js';
|
|
7
7
|
|
|
8
|
-
function sasQuery() {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
function sasQuery(_appContext) {
|
|
9
|
+
const isAgent = _appContext && _appContext.agent;
|
|
10
|
+
|
|
11
|
+
let description = isAgent ? `
|
|
12
|
+
sas-query — run a SQL aggregation query against a table.
|
|
13
|
+
PARAMS: table (string as lib.table, required), query (string, SQL WHERE/aggregation clause, required)
|
|
14
|
+
RETURNS: aggregated query result rows
|
|
15
|
+
` : `
|
|
16
|
+
sas-query - convert natural language questions into SQL queries and execute them.
|
|
12
17
|
|
|
13
18
|
USE when: how many/count/total/average by, aggregated analytics, complex filtering, statistical summaries
|
|
14
|
-
DO NOT USE for: raw reads without filtering (use read-table), table structure (use table-
|
|
19
|
+
DO NOT USE for: raw reads without filtering (use read-table), table structure (use table-describe), SAS programs (use program-score), jobs/jobdefs
|
|
15
20
|
|
|
16
21
|
PARAMETERS
|
|
17
|
-
- table: string
|
|
18
|
-
- query: string
|
|
19
|
-
- sql: string
|
|
20
|
-
- job: string (default: 'program')
|
|
22
|
+
- table: string — table in lib.table format (required), e.g. "Public.cars" or "sashelp.class"
|
|
23
|
+
- query: string — natural language question (required)
|
|
24
|
+
- sql: string — pre-generated SQL SELECT (optional, LLM generates)
|
|
25
|
+
- job: string (default: 'program') — job name to execute
|
|
21
26
|
|
|
22
27
|
ROUTING RULES
|
|
23
|
-
- "how many cars by make in sashelp.cars"
|
|
24
|
-
- "average salary by department in Public.employees"
|
|
28
|
+
- "how many cars by make in sashelp.cars" → { table: "sashelp.cars", query: "how many cars by make", sql: "SELECT make, COUNT(*) FROM sashelp.cars GROUP BY make" }
|
|
29
|
+
- "average salary by department in Public.employees" → { table: "Public.employees", query: "average salary by department", sql: "SELECT department, AVG(salary) FROM Public.employees GROUP BY department" }
|
|
25
30
|
|
|
26
31
|
EXAMPLES
|
|
27
|
-
- "how many cars by make in sashelp.cars"
|
|
28
|
-
- "total sales by region from mylib.sales"
|
|
32
|
+
- "how many cars by make in sashelp.cars" → { table: "sashelp.cars", query: "how many cars by make", sql: "SELECT make, COUNT(*) FROM sashelp.cars GROUP BY make" }
|
|
33
|
+
- "total sales by region from mylib.sales" → { table: "mylib.sales", query: "total sales by region", sql: "SELECT region, SUM(amount) FROM mylib.sales GROUP BY region" }
|
|
29
34
|
|
|
30
35
|
NEGATIVE EXAMPLES (do not route here)
|
|
31
36
|
- "read table cars" (use read-table)
|
|
32
37
|
- "show 10 rows" (use read-table)
|
|
33
|
-
- "table structure" (use table-
|
|
34
|
-
- "run SAS code" (use
|
|
35
|
-
- "
|
|
38
|
+
- "table structure" (use table-describe)
|
|
39
|
+
- "run SAS code" (use program-score)
|
|
40
|
+
- "score job/macro" (use job-score/macro-score)
|
|
36
41
|
|
|
37
42
|
ERRORS
|
|
38
43
|
Returns rows array, columns metadata, log. Returns error if SQL invalid or table not found.
|
|
@@ -75,3 +80,4 @@ Returns rows array, columns metadata, log. Returns error if SQL invalid or table
|
|
|
75
80
|
}
|
|
76
81
|
export default sasQuery;
|
|
77
82
|
|
|
83
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import _scrDescribe from '../toolHelpers/_scrDescribe.js';
|
|
8
|
+
|
|
9
|
+
function scrDescribe(_appContext) {
|
|
10
|
+
const isAgent = _appContext && _appContext.agent;
|
|
11
|
+
let description = isAgent ? `
|
|
12
|
+
scr-describe — return input/output schema for a SCR model.
|
|
13
|
+
PARAMS: intent ('describe', required), name (string, required)
|
|
14
|
+
RETURNS: input/output schema and model metadata
|
|
15
|
+
` : `
|
|
16
|
+
scr-describe - return the input/output schema and metadata for an SCR (Score Code Runtime) model.
|
|
17
|
+
|
|
18
|
+
Inputs
|
|
19
|
+
- intent: must be 'describe' — only pass if user explicitly asked to describe/inspect an SCR model. Do NOT use for find or verify existence.
|
|
20
|
+
- name (string): The SCR model identifier.
|
|
21
|
+
What it returns
|
|
22
|
+
- A JSON object describing the model's interface, typically including:
|
|
23
|
+
- Input variables (names, types, required/optional)
|
|
24
|
+
- Output variables (predictions, probabilities, scores)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Usage notes
|
|
28
|
+
- Ensure network connectivity and credentials for the remote SCR service when needed.
|
|
29
|
+
- Use scr-score to score data after inspecting the schema.
|
|
30
|
+
|
|
31
|
+
Examples
|
|
32
|
+
- describe scr model "loan"
|
|
33
|
+
- info for scr model "loan"
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
let spec = {
|
|
37
|
+
name: 'scr-describe',
|
|
38
|
+
description: description,
|
|
39
|
+
inputSchema: z.object({
|
|
40
|
+
intent: z.literal('describe'),
|
|
41
|
+
name: z.string()
|
|
42
|
+
}),
|
|
43
|
+
handler: async (params) => {
|
|
44
|
+
const { intent, name, _appContext } = params;
|
|
45
|
+
if (name === null) {
|
|
46
|
+
return { status: { statusCode: 2, msg: `SCR model ${name} not found` }, results: {} };
|
|
47
|
+
}
|
|
48
|
+
let r = await _scrDescribe({name, _appContext});
|
|
49
|
+
return r;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return spec;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default scrDescribe;
|
package/src/toolSet/scrScore.js
CHANGED
|
@@ -1,70 +1,63 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright
|
|
3
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { z } from 'zod';
|
|
7
|
-
import _scrScore from '../toolHelpers/_scrScore.js';
|
|
8
|
-
|
|
9
|
-
function scrScore(_appContext) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- When
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return spec;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export default scrScore;
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import _scrScore from '../toolHelpers/_scrScore.js';
|
|
8
|
+
|
|
9
|
+
function scrScore(_appContext) {
|
|
10
|
+
const isAgent = _appContext && _appContext.agent;
|
|
11
|
+
let description = isAgent ? `
|
|
12
|
+
scr-score — score a scenario using a SCR model endpoint.
|
|
13
|
+
PARAMS: name (string, required), scenario (object, optional)
|
|
14
|
+
RETURNS: SCR endpoint response with predictions merged with inputs
|
|
15
|
+
` : `
|
|
16
|
+
scr-score - score a scenario using a model deployed as a SCR container in Azure or another host.
|
|
17
|
+
|
|
18
|
+
Inputs
|
|
19
|
+
- name (string, required): SCR model identifier (URL)
|
|
20
|
+
- scenario (object, optional): Input values to score as a JSON object (e.g. {age:45, income:60000}). If omitted, defaults to {} and the tool will return the model's input variable definitions.
|
|
21
|
+
|
|
22
|
+
What it returns
|
|
23
|
+
- When scoring: the SCR endpoint response (predictions, probabilities, scores) merged with or alongside the supplied inputs.
|
|
24
|
+
- When \`scenario\` is omitted: metadata describing the model's input variables (names, types, required/optional).
|
|
25
|
+
|
|
26
|
+
Usage notes
|
|
27
|
+
- Run \`scr-describe\` first to inspect the expected input variables and types.
|
|
28
|
+
- Prefer structured objects for numeric/date values to avoid type ambiguity; the simple string parser keeps values as strings.
|
|
29
|
+
- Ensure network connectivity and any required credentials for the target SCR service.
|
|
30
|
+
|
|
31
|
+
Examples
|
|
32
|
+
- scrScore with name="loan" and scenario={age:45, income:60000}
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
let spec = {
|
|
36
|
+
name: 'scr-score',
|
|
37
|
+
description: description,
|
|
38
|
+
inputSchema: z.object({
|
|
39
|
+
name: z.string(),
|
|
40
|
+
scenario: z.union([z.record(z.any()), z.string()]).optional()
|
|
41
|
+
}),
|
|
42
|
+
|
|
43
|
+
handler: async (params) => {
|
|
44
|
+
let {name, _appContext} = params;
|
|
45
|
+
let scenario = params.scenario;
|
|
46
|
+
if (typeof scenario === 'string') {
|
|
47
|
+
try { scenario = JSON.parse(scenario); } catch { scenario = {}; }
|
|
48
|
+
}
|
|
49
|
+
if (name === null) {
|
|
50
|
+
return { status: { statusCode: 2, msg: `SCR model ${name} was not specified` }, results: {} };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const scenarioObj = (scenario != null && typeof scenario === 'object') ? scenario : {};
|
|
54
|
+
|
|
55
|
+
let r = await _scrScore({ name: name, scenario: scenarioObj, _appContext: _appContext});
|
|
56
|
+
return r;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return spec;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default scrScore;
|
|
@@ -11,7 +11,7 @@ function searchAssets(_appContext) {
|
|
|
11
11
|
const log = debug('tools');
|
|
12
12
|
|
|
13
13
|
let description = `
|
|
14
|
-
|
|
14
|
+
search-assets - Search the SAS Catalog for assets using a flexible search string.
|
|
15
15
|
|
|
16
16
|
- Supports searching for various asset types (e.g., datasets, dataflows, models).
|
|
17
17
|
- the default asset type is 'datasets'.
|
|
@@ -6,11 +6,16 @@
|
|
|
6
6
|
import {z} from 'zod';
|
|
7
7
|
|
|
8
8
|
function setContext(_appContext) {
|
|
9
|
-
|
|
9
|
+
const isAgent = _appContext && _appContext.agent;
|
|
10
|
+
let description = isAgent ? `
|
|
11
|
+
set-context — set runtime context variables (CAS server, SAS server, etc.).
|
|
12
|
+
PARAMS: cas (string, optional), sas (string, optional), other key=value context fields
|
|
13
|
+
RETURNS: updated context confirmation
|
|
14
|
+
` : `
|
|
10
15
|
set-context — set the CAS and SAS server contexts for subsequent tool calls.
|
|
11
16
|
|
|
12
17
|
USE when: switch to CAS server, change compute context, check current context, set both
|
|
13
|
-
DO NOT USE for: get variables (use get-env), read data (use read-table),
|
|
18
|
+
DO NOT USE for: get variables (use get-env), read data (use read-table), score programs (use program-score)
|
|
14
19
|
|
|
15
20
|
PARAMETERS
|
|
16
21
|
- cas: string — CAS server name (optional), e.g. 'cas-shared-default', 'finance-cas-server'
|
|
@@ -30,7 +35,7 @@ EXAMPLES
|
|
|
30
35
|
NEGATIVE EXAMPLES (do not route here)
|
|
31
36
|
- "read table cars" (use read-table)
|
|
32
37
|
- "what's the value of X" (use get-env)
|
|
33
|
-
- "
|
|
38
|
+
- "score program" (use program-score)
|
|
34
39
|
|
|
35
40
|
ERRORS
|
|
36
41
|
Returns current or updated context values {cas, sas}. Error if server not found or invalid name.
|
package/src/toolSet/superstat.js
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
*/
|
|
5
|
-
import { type } from 'node:os';
|
|
6
|
-
import _submitCode from '../toolHelpers/_submitCode.js';
|
|
7
|
-
import { z } from 'zod';
|
|
8
|
-
|
|
9
|
-
function superstat(_appContext) {
|
|
10
|
-
let desc = `
|
|
11
|
-
## superstat: compute superstat for two numbers using SAS programming
|
|
12
|
-
|
|
13
|
-
## Details
|
|
14
|
-
This is a tool to demonstrate using SAS programming to score. The SAS program for suprestat is
|
|
15
|
-
below. In a real application this would be a more complex program that is
|
|
16
|
-
available to the SAS server.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
ods html style=barrettsblue;
|
|
20
|
-
data temp;
|
|
21
|
-
superstat = (&a + &b) * 42;
|
|
22
|
-
run;
|
|
23
|
-
proc print data=temp;
|
|
24
|
-
run;
|
|
25
|
-
ods html close;
|
|
26
|
-
run;
|
|
27
|
-
|
|
28
|
-
## Sample Prompt
|
|
29
|
-
|
|
30
|
-
- compute superstat for 1 and 2
|
|
31
|
-
- compute superstat for 3,5
|
|
32
|
-
|
|
33
|
-
`;
|
|
34
|
-
let spec = {
|
|
35
|
-
name: 'superstat',
|
|
36
|
-
description: desc,
|
|
37
|
-
inputSchema: z.object({
|
|
38
|
-
a: z.number().optional()
|
|
39
|
-
}),
|
|
40
|
-
required: ['a', 'b']
|
|
41
|
-
},
|
|
42
|
-
handler: async (params) => {
|
|
43
|
-
let src = `
|
|
44
|
-
ods html style=barrettsblue;
|
|
45
|
-
data temp;
|
|
46
|
-
superstat = (&a + &b) * 42;
|
|
47
|
-
run;
|
|
48
|
-
proc print data=temp;
|
|
49
|
-
run;
|
|
50
|
-
ods html close;
|
|
51
|
-
run;
|
|
52
|
-
`;
|
|
53
|
-
params.src = src;
|
|
54
|
-
let r = await _submitCode(params);
|
|
55
|
-
return r;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
};
|
|
59
|
-
return spec;
|
|
60
|
-
}
|
|
61
|
-
export default superstat;
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { type } from 'node:os';
|
|
6
|
+
import _submitCode from '../toolHelpers/_submitCode.js';
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
function superstat(_appContext) {
|
|
10
|
+
let desc = `
|
|
11
|
+
## superstat: compute superstat for two numbers using SAS programming
|
|
12
|
+
|
|
13
|
+
## Details
|
|
14
|
+
This is a tool to demonstrate using SAS programming to score. The SAS program for suprestat is
|
|
15
|
+
below. In a real application this would be a more complex program that is
|
|
16
|
+
available to the SAS server.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
ods html style=barrettsblue;
|
|
20
|
+
data temp;
|
|
21
|
+
superstat = (&a + &b) * 42;
|
|
22
|
+
run;
|
|
23
|
+
proc print data=temp;
|
|
24
|
+
run;
|
|
25
|
+
ods html close;
|
|
26
|
+
run;
|
|
27
|
+
|
|
28
|
+
## Sample Prompt
|
|
29
|
+
|
|
30
|
+
- compute superstat for 1 and 2
|
|
31
|
+
- compute superstat for 3,5
|
|
32
|
+
|
|
33
|
+
`;
|
|
34
|
+
let spec = {
|
|
35
|
+
name: 'superstat',
|
|
36
|
+
description: desc,
|
|
37
|
+
inputSchema: z.object({
|
|
38
|
+
a: z.number().optional()
|
|
39
|
+
}),
|
|
40
|
+
required: ['a', 'b']
|
|
41
|
+
},
|
|
42
|
+
handler: async (params) => {
|
|
43
|
+
let src = `
|
|
44
|
+
ods html style=barrettsblue;
|
|
45
|
+
data temp;
|
|
46
|
+
superstat = (&a + &b) * 42;
|
|
47
|
+
run;
|
|
48
|
+
proc print data=temp;
|
|
49
|
+
run;
|
|
50
|
+
ods html close;
|
|
51
|
+
run;
|
|
52
|
+
`;
|
|
53
|
+
params.src = src;
|
|
54
|
+
let r = await _submitCode(params);
|
|
55
|
+
return r;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
};
|
|
59
|
+
return spec;
|
|
60
|
+
}
|
|
61
|
+
export default superstat;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import debug from 'debug';
|
|
7
|
+
|
|
8
|
+
import _tableInfo from '../toolHelpers/_tableDescribe.js';
|
|
9
|
+
function tableDescribe(_appContext) {
|
|
10
|
+
const isAgent = _appContext && _appContext.agent;
|
|
11
|
+
let describe = isAgent ? `
|
|
12
|
+
table-describe — return column schema for a table.
|
|
13
|
+
PARAMS: intent ('describe', required), lib (string, required), table (string, required), server ('cas'|'sas', required)
|
|
14
|
+
RETURNS: column names, types, labels, formats; table row count and file size
|
|
15
|
+
` : `
|
|
16
|
+
table-describe - retrieve metadata about a table in a CAS or SAS library.
|
|
17
|
+
|
|
18
|
+
USE when: what columns, describe structure, show schema, table statistics, column info
|
|
19
|
+
DO NOT USE for: read data (use read-table), list tables (use list-tables), find table (use find-table), queries (use sas-query)
|
|
20
|
+
|
|
21
|
+
PARAMETERS
|
|
22
|
+
- intent: must be 'describe' — only pass if user explicitly asked to describe/inspect table structure. Do NOT use for read data, find table, or verify existence.
|
|
23
|
+
- table: string — table name (required)
|
|
24
|
+
- lib: string — caslib or libref (required)
|
|
25
|
+
- server: string (default: 'cas') — 'cas' or 'sas'
|
|
26
|
+
|
|
27
|
+
ROUTING RULES
|
|
28
|
+
- "what columns are in cars" → { table: "cars", lib: "<lib>", server: "cas" }
|
|
29
|
+
- "describe table sales in Public" → { table: "sales", lib: "Public", server: "cas" }
|
|
30
|
+
- "show schema for mylib.iris on sas" → { table: "iris", lib: "mylib", server: "sas" }
|
|
31
|
+
|
|
32
|
+
EXAMPLES
|
|
33
|
+
- "what columns in cars" → { table: "cars", lib: "<lib>", server: "cas" }
|
|
34
|
+
- "describe structure of customers in Public" → { table: "customers", lib: "Public", server: "cas" }
|
|
35
|
+
|
|
36
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
37
|
+
- "read table cars" (use read-table)
|
|
38
|
+
- "list tables in Public" (use list-tables)
|
|
39
|
+
- "does table exist" (use find-table)
|
|
40
|
+
- "query table" (use sas-query)
|
|
41
|
+
|
|
42
|
+
ERRORS
|
|
43
|
+
Returns { columns: [...], sampleData: [...] }. Error if table not found or server unreachable.
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
let specs = {
|
|
47
|
+
name: 'table-describe',
|
|
48
|
+
description: describe,
|
|
49
|
+
inputSchema: z.object({
|
|
50
|
+
intent: z.literal('describe'),
|
|
51
|
+
table: z.string(),
|
|
52
|
+
lib: z.string().optional(),
|
|
53
|
+
server: z.string().optional()
|
|
54
|
+
}),
|
|
55
|
+
handler: async (params) => {
|
|
56
|
+
const { intent, ...rest } = params;
|
|
57
|
+
rest.tool = 'describe';
|
|
58
|
+
let r = await _tableInfo(rest);
|
|
59
|
+
return r;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return specs;
|
|
63
|
+
}
|
|
64
|
+
export default tableDescribe;
|
|
65
|
+
|