@sassoftware/sas-score-mcp-serverjs 0.0.2
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/.babelrc +6 -0
- package/.env +13 -0
- package/.env.http +29 -0
- package/CHANGES.md +2 -0
- package/CONTRIBUTING.md +14 -0
- package/ContributorAgreement.txt +56 -0
- package/LICENSE +205 -0
- package/LICENSES.json +105 -0
- package/QUICK_REFERENCE.md +378 -0
- package/README.md +267 -0
- package/SECURITY.md +31 -0
- package/SUPPORT.md +3 -0
- package/TOOL_DESCRIPTION_TEMPLATE.md +157 -0
- package/TOOL_UPDATES_SUMMARY.md +208 -0
- package/cli.js +214 -0
- package/labs/.subclass.json +13 -0
- package/labs/README.md +4 -0
- package/mcpConfigurations/README.md +3 -0
- package/mcpConfigurations/http.json +8 -0
- package/mcpConfigurations/stdio.json +20 -0
- package/mcpConfigurations/stdiodev.json +20 -0
- package/mcpserver.png +0 -0
- package/openApi.json +106 -0
- package/openApi.yaml +84 -0
- package/package.json +72 -0
- package/sas-mcp-tools-reference.md +600 -0
- package/sasCode/sas-sql-query.sas +33 -0
- package/sasCode/sas_sql_tool.json +237 -0
- package/scripts/getViyaca.sh +8 -0
- package/src/core.js +19 -0
- package/src/coreSSE.js +14 -0
- package/src/corehttp.js +335 -0
- package/src/createHttpTransport.js +26 -0
- package/src/createMcpServer.js +76 -0
- package/src/db/scrModels.js +23 -0
- package/src/toolSet/devaScore.js +69 -0
- package/src/toolSet/findJob.js +90 -0
- package/src/toolSet/findJobdef.js +95 -0
- package/src/toolSet/findLibrary.js +100 -0
- package/src/toolSet/findModel.js +83 -0
- package/src/toolSet/findTable.js +94 -0
- package/src/toolSet/getEnv.js +72 -0
- package/src/toolSet/listJobdefs.js +96 -0
- package/src/toolSet/listJobs.js +110 -0
- package/src/toolSet/listLibraries.js +90 -0
- package/src/toolSet/listModels.js +83 -0
- package/src/toolSet/listTables.js +95 -0
- package/src/toolSet/makeTools.js +75 -0
- package/src/toolSet/mcp server .png +0 -0
- package/src/toolSet/modelInfo.js +87 -0
- package/src/toolSet/modelScore.js +131 -0
- package/src/toolSet/readTable.js +104 -0
- package/src/toolSet/runCasProgram.js +118 -0
- package/src/toolSet/runJob.js +81 -0
- package/src/toolSet/runJobdef.js +85 -0
- package/src/toolSet/runMacro.js +82 -0
- package/src/toolSet/runProgram.js +145 -0
- package/src/toolSet/sasQuery.js +126 -0
- package/src/toolSet/sasQueryTemplate.js +148 -0
- package/src/toolSet/sasQueryTemplate2.js +140 -0
- package/src/toolSet/scrInfo.js +55 -0
- package/src/toolSet/scrScore.js +71 -0
- package/src/toolSet/searchAssets.js +52 -0
- package/src/toolSet/setContext.js +98 -0
- package/src/toolSet/superstat.js +60 -0
- package/src/toolSet/tableInfo.js +102 -0
- package/src/toolhelpers/_catalogSearch.js +87 -0
- package/src/toolhelpers/_getEnv.js +10 -0
- package/src/toolhelpers/_itemsData.js +28 -0
- package/src/toolhelpers/_jobSubmit.js +78 -0
- package/src/toolhelpers/_listJobdefs.js +59 -0
- package/src/toolhelpers/_listJobs.js +63 -0
- package/src/toolhelpers/_listLibrary.js +56 -0
- package/src/toolhelpers/_listModels.js +41 -0
- package/src/toolhelpers/_listTables.js +52 -0
- package/src/toolhelpers/_masDescribe.js +27 -0
- package/src/toolhelpers/_masScoring.js +64 -0
- package/src/toolhelpers/_readTable.js +69 -0
- package/src/toolhelpers/_scrInfo.js +32 -0
- package/src/toolhelpers/_scrScore.js +49 -0
- package/src/toolhelpers/_submitCasl.js +34 -0
- package/src/toolhelpers/_submitCode.js +96 -0
- package/src/toolhelpers/_submitMacro.js +24 -0
- package/src/toolhelpers/_tableColumns.js +61 -0
- package/src/toolhelpers/_tableInfo.js +72 -0
- package/src/toolhelpers/deleteSession.js +13 -0
- package/src/toolhelpers/getLogonPayload.js +100 -0
- package/src/toolhelpers/getOpts.js +43 -0
- package/src/toolhelpers/getOptsViya.js +38 -0
- package/src/toolhelpers/getStoreOpts.js +18 -0
- package/src/toolhelpers/getToken.js +40 -0
- package/src/toolhelpers/refreshToken.js +48 -0
- package/test/README.md +63 -0
- package/test/listLibraries.test.js +245 -0
- package/tool-developer-guide.md +80 -0
- package/types.js +25 -0
|
@@ -0,0 +1,72 @@
|
|
|
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 _getEnv from '../toolHelpers/_getEnv.js';
|
|
8
|
+
function getEnv(_appContext) {
|
|
9
|
+
let description = `
|
|
10
|
+
## get-env — retrieve a variable value from the runtime environment
|
|
11
|
+
|
|
12
|
+
LLM Invocation Guidance (When to use)
|
|
13
|
+
Use THIS tool when:
|
|
14
|
+
- The user wants to access a specific environment variable or context value
|
|
15
|
+
- "What is the value of [variable name]?"
|
|
16
|
+
- "Get me the [variable] value"
|
|
17
|
+
- "Show the current [variable]"
|
|
18
|
+
|
|
19
|
+
Do NOT use this tool for:
|
|
20
|
+
- Retrieving table data (use read-table)
|
|
21
|
+
- Getting model information (use model-info)
|
|
22
|
+
- Looking up job status (use find-job or run-job)
|
|
23
|
+
- Setting environment variables (use set-context to set CAS/SAS contexts)
|
|
24
|
+
|
|
25
|
+
Purpose
|
|
26
|
+
Retrieve the current value of a named variable from the runtime environment. This is useful for debugging, accessing context information, or verifying current configuration values.
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
- name (string, required): The name of the variable to retrieve. Variable names are case-sensitive.
|
|
30
|
+
|
|
31
|
+
Response Contract
|
|
32
|
+
Returns a JSON object containing:
|
|
33
|
+
- The requested variable name as a key
|
|
34
|
+
- The current value of that variable
|
|
35
|
+
- If the variable does not exist, returns null or an error message
|
|
36
|
+
|
|
37
|
+
Disambiguation & Clarification
|
|
38
|
+
- If variable name is missing: ask "Which variable would you like to retrieve?"
|
|
39
|
+
- If user says "context" without specifying which variable: clarify "Do you mean the CAS context, SAS context, or a specific variable?"
|
|
40
|
+
- Multiple variable request: handle one at a time or ask for clarification
|
|
41
|
+
|
|
42
|
+
Examples (→ mapped params)
|
|
43
|
+
- "What's the value of myVar" → { name: "myVar" }
|
|
44
|
+
- "Get me the configuration variable" → { name: "configuration" }
|
|
45
|
+
- "Show the current server setting" → { name: "server" }
|
|
46
|
+
|
|
47
|
+
Negative Examples (should NOT call get-env)
|
|
48
|
+
- "Read all rows from the customers table" (use read-table instead)
|
|
49
|
+
- "Get model details for myModel" (use model-info instead)
|
|
50
|
+
- "Set the CAS server to finance-prod" (use set-context instead)
|
|
51
|
+
|
|
52
|
+
Related Tools
|
|
53
|
+
- setContext — to set environment context values (CAS and SAS servers)
|
|
54
|
+
- readTable — to retrieve table data
|
|
55
|
+
- modelInfo — to retrieve model metadata
|
|
56
|
+
`;
|
|
57
|
+
|
|
58
|
+
let spec = {
|
|
59
|
+
name: 'get-env',
|
|
60
|
+
aliases: ['get-env','get env','get environment'],
|
|
61
|
+
description: description,
|
|
62
|
+
schema: {
|
|
63
|
+
name: z.string()
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
handler: async (params) => {
|
|
67
|
+
return await _getEnv(params);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return spec;
|
|
71
|
+
}
|
|
72
|
+
export default getEnv;
|
|
@@ -0,0 +1,96 @@
|
|
|
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 _listJobdefs from '../toolHelpers/_listJobdefs.js';
|
|
7
|
+
function listJobdefs(_appContext) {
|
|
8
|
+
|
|
9
|
+
let description = `
|
|
10
|
+
## list-jobdefs — enumerate SAS Viya job definitions assets(jobdefs)
|
|
11
|
+
|
|
12
|
+
LLM Invocation Guidance (When to use)
|
|
13
|
+
jobdef and jobdefs are used interchangeably here to refer to job definitions.
|
|
14
|
+
Use THIS tool when the user wants to browse or list many job definitions assets
|
|
15
|
+
- "list jobdefs"
|
|
16
|
+
- "show jobdefs"
|
|
17
|
+
- "list available jobdefs"
|
|
18
|
+
- "browse jobdefs"
|
|
19
|
+
- "next jobdefs" (after a previous page)
|
|
20
|
+
- "list 25 jobdefs" / "list jobdefs limit 25"
|
|
21
|
+
Do NOT use this tool for:
|
|
22
|
+
- Checking existence of ONE job (use find-job)
|
|
23
|
+
- Executing/running a job (use run-job)
|
|
24
|
+
- Running a job definition (use run-jobdef)
|
|
25
|
+
- Submitting SAS code (use run-sas-program)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
Purpose
|
|
29
|
+
Page through jobdef assets deployed/registered in SAS Viya.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
- limit (number, default 10): Number of jobs to return.
|
|
33
|
+
- start (number, default 1): 1-based offset for paging.
|
|
34
|
+
- where (string, optional): Filter expression (future use / passthrough; empty string by default). If unsupported, it may be ignored gracefully.
|
|
35
|
+
|
|
36
|
+
Response Contract
|
|
37
|
+
- Returns an array of jobdef names or objects (backend-dependent) inside structuredContent.
|
|
38
|
+
- If items.length === limit, caller may request next page using start + limit.
|
|
39
|
+
- Provide optional hint start = start + limit when page might continue.
|
|
40
|
+
|
|
41
|
+
Pagination Examples
|
|
42
|
+
- First page: { start:1, limit:10 }
|
|
43
|
+
- Next page: { start:11, limit:10 }
|
|
44
|
+
|
|
45
|
+
Disambiguation & Clarification
|
|
46
|
+
- Input only "list" → ask: "Specify asset to list? (Say 'Please specify what to listlist' to proceed)" unless prior context indicates job definition listing.
|
|
47
|
+
- Input contains "run"/"execute" plus job name → route to job/jobdef.
|
|
48
|
+
|
|
49
|
+
Negative Examples (should NOT call list-jobdefs)
|
|
50
|
+
- "list libraries" (use list-libraries)
|
|
51
|
+
- "list tables" (use list-tables)
|
|
52
|
+
- "list models" (use list-models)
|
|
53
|
+
- "list jobs" (use list-jobs)
|
|
54
|
+
- "find job abc" (findJob)
|
|
55
|
+
- "run job abc" (job)
|
|
56
|
+
- "job abc" (job)
|
|
57
|
+
- "find model xyz" (findModel)
|
|
58
|
+
- "list models" (listModels)
|
|
59
|
+
- "list tables in lib xyz" (listTables)
|
|
60
|
+
- "show me libraries" (listLibraries)
|
|
61
|
+
- "describe job abc" (findJob then possibly job for execution)
|
|
62
|
+
|
|
63
|
+
Error Handling
|
|
64
|
+
- On backend error: surface structured error payload (do not fabricate job names).
|
|
65
|
+
- Empty page (items.length === 0) with start > 1 may mean caller paged past end.
|
|
66
|
+
|
|
67
|
+
Usage Tips
|
|
68
|
+
- Increase limit for fewer round trips; keep reasonable to avoid large payloads.
|
|
69
|
+
- Combine with findJobdeffor confirmation before execution.
|
|
70
|
+
|
|
71
|
+
Examples (→ mapped params)
|
|
72
|
+
- "list jobdefs" → { start:1, limit:10 }
|
|
73
|
+
- "list 25 jobdefs" → { start:1, limit:25 }
|
|
74
|
+
- "next jobdefs" (after prior {start:1,limit:10}) → { start:11, limit:10 }
|
|
75
|
+
`;
|
|
76
|
+
|
|
77
|
+
let spec = {
|
|
78
|
+
name: 'list-jobdefs',
|
|
79
|
+
aliases: ['listJobdefs','list jobdefs','list_jobdefs'],
|
|
80
|
+
description: description,
|
|
81
|
+
schema: {
|
|
82
|
+
limit: z.number().default(10),
|
|
83
|
+
start: z.number().default(1),
|
|
84
|
+
where: z.string().default('')
|
|
85
|
+
},
|
|
86
|
+
// No 'server' required; backend context is implicit in helper
|
|
87
|
+
required: [],
|
|
88
|
+
handler: async (params) => {
|
|
89
|
+
// _listJobdefs handles all validation and defaults
|
|
90
|
+
const result = await _listJobdefs(params);
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return spec;
|
|
95
|
+
}
|
|
96
|
+
export default listJobdefs;
|
|
@@ -0,0 +1,110 @@
|
|
|
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 _listJobs from '../toolHelpers/_listJobs.js';
|
|
7
|
+
function listJobs(_appContext) {
|
|
8
|
+
// LLM guidance object retained for potential future consumption; not exported directly.
|
|
9
|
+
let llmDescription = {
|
|
10
|
+
purpose: "Map natural language requests to listJobs parameters and return a machine-readable response.",
|
|
11
|
+
param_mapping: {
|
|
12
|
+
limit: "positive integer. if not specified, set limit to 10",
|
|
13
|
+
start: "1-indexed offset. if not specified, set start to 1",
|
|
14
|
+
where: "optional filter string, default '' (may be ignored)"
|
|
15
|
+
},
|
|
16
|
+
response_schema: "{ jobs: string[] , start?: number }",
|
|
17
|
+
behavior: "Return only JSON matching response_schema. If ambiguous, ask at most one clarifying question. If no results, return { jobs: [] }. Include start when a full page is returned.",
|
|
18
|
+
examples: [
|
|
19
|
+
{ input: "list jobs", mapped_params: { start: 1, limit: 10 } },
|
|
20
|
+
{ input: "show me jobs, 20 per page", mapped_params: { start: 1, limit: 20 } },
|
|
21
|
+
{ input: "next jobs", note: "interpret as start = previousStart + previousLimit" }
|
|
22
|
+
],
|
|
23
|
+
safety: "Surface backend errors directly; do not hallucinate job names."
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
let description = `
|
|
27
|
+
## list-jobs — enumerate SAS Viya job assets
|
|
28
|
+
|
|
29
|
+
LLM Invocation Guidance (When to use)
|
|
30
|
+
Use THIS tool when the user wants to browse or list many job definitions / job assets:
|
|
31
|
+
- "list jobs"
|
|
32
|
+
- "show jobs"
|
|
33
|
+
- "list available jobs"
|
|
34
|
+
- "browse jobs"
|
|
35
|
+
- "next jobs" (after a previous page)
|
|
36
|
+
- "list 25 jobs" / "list jobs limit 25"
|
|
37
|
+
|
|
38
|
+
Do NOT use this tool for:
|
|
39
|
+
- Checking existence of ONE job (use find-job)
|
|
40
|
+
- Executing/running a job (use run-job)
|
|
41
|
+
- Running a job definition (use run-jobdef)
|
|
42
|
+
- Submitting SAS code (use run-sas-program)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
Purpose
|
|
46
|
+
Page through job assets deployed/registered in SAS Viya Job Execution service.
|
|
47
|
+
|
|
48
|
+
Parameters
|
|
49
|
+
- limit (number, default 10): Number of jobs to return.
|
|
50
|
+
- start (number, default 1): 1-based offset for paging.
|
|
51
|
+
- where (string, optional): Filter expression (future use / passthrough; empty string by default). If unsupported, it may be ignored gracefully.
|
|
52
|
+
|
|
53
|
+
Response Contract
|
|
54
|
+
- Returns an array of job names or objects (backend-dependent) inside structuredContent.
|
|
55
|
+
- If items.length === limit, caller may request next page using start + limit.
|
|
56
|
+
- Provide optional hint start = start + limit when page might continue.
|
|
57
|
+
|
|
58
|
+
Pagination Examples
|
|
59
|
+
- First page: { start:1, limit:10 }
|
|
60
|
+
- Next page: { start:11, limit:10 }
|
|
61
|
+
|
|
62
|
+
Disambiguation & Clarification
|
|
63
|
+
- Input only "list" → ask: "List jobs? (Say 'list jobs' to proceed)" unless prior context indicates jobs listing.
|
|
64
|
+
- "find job X" → route to findJob instead.
|
|
65
|
+
- Input contains "run"/"execute" plus job name → route to job/jobdef.
|
|
66
|
+
|
|
67
|
+
Negative Examples (should NOT call list-jobs)
|
|
68
|
+
- "find job abc" (find-job)
|
|
69
|
+
- "run job abc" (run-job)
|
|
70
|
+
- "job abc" (run-job)
|
|
71
|
+
- "find model xyz" (find-model)
|
|
72
|
+
- "list models" (list-models)
|
|
73
|
+
- "list tables in lib xyz" (list-tables)
|
|
74
|
+
- "show me libraries" (list-libraries)
|
|
75
|
+
- "describe job abc" (find-job then possibly run-job for execution)
|
|
76
|
+
|
|
77
|
+
Error Handling
|
|
78
|
+
- On backend error: surface structured error payload (do not fabricate job names).
|
|
79
|
+
- Empty page (items.length === 0) with start > 1 may mean caller paged past end.
|
|
80
|
+
|
|
81
|
+
Usage Tips
|
|
82
|
+
- Increase limit for fewer round trips; keep reasonable to avoid large payloads.
|
|
83
|
+
- Combine with findJob for confirmation before execution.
|
|
84
|
+
|
|
85
|
+
Examples (→ mapped params)
|
|
86
|
+
- "list jobs" → { start:1, limit:10 }
|
|
87
|
+
- "list 25 jobs" → { start:1, limit:25 }
|
|
88
|
+
- "next jobs" (after prior {start:1,limit:10}) → { start:11, limit:10 }
|
|
89
|
+
`;
|
|
90
|
+
|
|
91
|
+
let spec = {
|
|
92
|
+
name: 'list-jobs',
|
|
93
|
+
aliases: ['listJobs','list jobs','list_jobs'],
|
|
94
|
+
description: description,
|
|
95
|
+
schema: {
|
|
96
|
+
limit: z.number().default(10),
|
|
97
|
+
start: z.number().default(1),
|
|
98
|
+
where: z.string().default('')
|
|
99
|
+
},
|
|
100
|
+
// No 'server' required; backend context is implicit in helper
|
|
101
|
+
required: [],
|
|
102
|
+
handler: async (params) => {
|
|
103
|
+
// _listJob handles all validation and defaults
|
|
104
|
+
const result = await _listJobs(params);
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return spec;
|
|
109
|
+
}
|
|
110
|
+
export default listJobs;
|
|
@@ -0,0 +1,90 @@
|
|
|
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 _listLibrary from '../toolHelpers/_listLibrary.js';
|
|
7
|
+
function listLibraries(_appContext) {
|
|
8
|
+
|
|
9
|
+
let description = `
|
|
10
|
+
## list-libraries — enumerate CAS or SAS libraries
|
|
11
|
+
|
|
12
|
+
LLM Invocation Guidance (critical)
|
|
13
|
+
Use THIS tool when the user asks for: "list libs", "list libraries", "show cas libs", "show sas libs", "what libraries are available", "list caslib(s)", "enumerate libraries", "libraries in cas", "libraries in sas".
|
|
14
|
+
DO NOT use this tool when the user asks for: tables inside a specific library (choose listTables), columns/metadata of a table, job/program execution, models, or scoring.
|
|
15
|
+
|
|
16
|
+
Trigger Phrase → Parameter Mapping
|
|
17
|
+
- "cas libs" / "in cas" / "cas libraries" → { server: 'cas' }
|
|
18
|
+
- "sas libs" / "in sas" / "base sas libraries" → { server: 'sas' }
|
|
19
|
+
- "next" (after prior call) → { start: previous.start + previous.limit }
|
|
20
|
+
- "first 20 cas libs" → { server: 'cas', limit: 20 }
|
|
21
|
+
- If server unspecified: default to CAS.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
- server (cas|sas, default 'cas')
|
|
25
|
+
- limit (integer > 0, default 10)
|
|
26
|
+
- start (1-based offset, default 1)
|
|
27
|
+
- where (optional filter expression, default '')
|
|
28
|
+
|
|
29
|
+
Response Contract
|
|
30
|
+
Return JSON-like structure from helper; consumers may extract an array of library objects/names. If number of returned items === limit supply a pagination hint: start = start + limit.
|
|
31
|
+
|
|
32
|
+
Behavior Summary
|
|
33
|
+
- Pure listing; no side effects.
|
|
34
|
+
- If ambiguous short request like "list" or "libs" and no prior context: assume { server: 'cas' }.
|
|
35
|
+
- If user explicitly asks for ALL (e.g. "all cas libs") and count likely large, honor limit=50 unless user supplies a value; include note about paging.
|
|
36
|
+
|
|
37
|
+
Disambiguation Rules
|
|
38
|
+
- If user mentions a singular library name plus desire for tables ("list tables in SASHELP") choose listTables (not this tool).
|
|
39
|
+
- If user mixes "tables" and "libraries" ask for clarification unless clearly about libraries.
|
|
40
|
+
|
|
41
|
+
Examples
|
|
42
|
+
- "list libraries" → { server: 'cas', start:1, limit:10 }
|
|
43
|
+
- "list libs" → { server: 'cas', start:1, limit:10 }
|
|
44
|
+
- "list sas libs" → { server: 'sas' }
|
|
45
|
+
- "show me 25 cas libraries" → { server:'cas', limit:25 }
|
|
46
|
+
- "next" (after prior call {start:1,limit:10}) → { start:11, limit:10 }
|
|
47
|
+
- "filter cas libs" (no criterion) → ask: "Provide a filter or continue without one?"
|
|
48
|
+
|
|
49
|
+
Negative Examples (do not route here)
|
|
50
|
+
- "list tables in public" (route to list-tables)
|
|
51
|
+
- "list models, list tables, list jobs, list jobdef and similar request"
|
|
52
|
+
- "describe library" (likely list-tables or table-info depending on follow-up)
|
|
53
|
+
- "run program to make a lib" (run-sas-program tool)
|
|
54
|
+
|
|
55
|
+
Error Handling
|
|
56
|
+
- On backend error: return structured error with message field; do not hallucinate libraries.
|
|
57
|
+
- Empty result set → return empty list plus (if start>1) a hint that paging may have exceeded available items.
|
|
58
|
+
|
|
59
|
+
Rationale
|
|
60
|
+
Concise, signal-rich description increases probability this spec is selected for generic library enumeration intents.
|
|
61
|
+
`;
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
// Canonical kebab-case tool name; legacy aliases preserved for compatibility
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
let spec = {
|
|
68
|
+
name: 'list-libraries',
|
|
69
|
+
aliases: ['listLibraries','list libraries','list_libraries'],
|
|
70
|
+
description: description,
|
|
71
|
+
schema: {
|
|
72
|
+
server: z.string().default('cas'),
|
|
73
|
+
limit: z.number().default(10),
|
|
74
|
+
start: z.number().default(1), // added default to match documentation
|
|
75
|
+
where: z.string().default('')
|
|
76
|
+
},
|
|
77
|
+
// 'server' has a default so we don't mark it required
|
|
78
|
+
required: [],
|
|
79
|
+
handler: async (params) => {
|
|
80
|
+
// normalize server just in case caller sends 'CAS'/'SAS'
|
|
81
|
+
params.server = (params.server || 'cas').toLowerCase();
|
|
82
|
+
|
|
83
|
+
let r = await _listLibrary(params);
|
|
84
|
+
return r;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
return spec;
|
|
88
|
+
}
|
|
89
|
+
export default listLibraries;
|
|
90
|
+
|
|
@@ -0,0 +1,83 @@
|
|
|
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 _listModels from '../toolHelpers/_listModels.js';
|
|
8
|
+
|
|
9
|
+
function listModels(_appContext) {
|
|
10
|
+
let description = `
|
|
11
|
+
## list-models — enumerate models published to MAS (Model Publish / Scoring service)
|
|
12
|
+
|
|
13
|
+
LLM Invocation Guidance (When to use)
|
|
14
|
+
Use THIS tool when the user wants a collection of models, e.g.:
|
|
15
|
+
- "list models"
|
|
16
|
+
- "show models"
|
|
17
|
+
- "list available models"
|
|
18
|
+
- "browse models"
|
|
19
|
+
- "list 25 models" / "list models limit 25"
|
|
20
|
+
- "next models" (after a previous page)
|
|
21
|
+
|
|
22
|
+
Do NOT use this tool for:
|
|
23
|
+
- Checking a single model's existence (use find-model)
|
|
24
|
+
- Getting model metadata / variables (use model-info)
|
|
25
|
+
- Scoring a model (use model-score)
|
|
26
|
+
- list libraries, tables, jobs, or jobdefs (use respective list/find tools)
|
|
27
|
+
- Looking up jobs, libraries, tables, or SCR endpoints (route to respective tools)
|
|
28
|
+
|
|
29
|
+
Purpose
|
|
30
|
+
Provide a paginated view of MAS-registered models so the caller can then drill into one via modelInfo or score it.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
- limit (number, default 10): Number of models to return for this page.
|
|
34
|
+
- start (number, default 1): 1-based offset. For paging: start = start + limit.
|
|
35
|
+
|
|
36
|
+
Response Contract
|
|
37
|
+
- Returns an array of model entries (names or metadata objects). Empty array if no models.
|
|
38
|
+
- If returned length === limit, caller may request the next page.
|
|
39
|
+
|
|
40
|
+
Pagination Examples
|
|
41
|
+
- First page: { start:1, limit:10 }
|
|
42
|
+
- Next page: { start:11, limit:10 }
|
|
43
|
+
|
|
44
|
+
Disambiguation & Clarification
|
|
45
|
+
- Input only "list" → ask: "List models? (Say 'list models' to proceed)" unless prior context strongly indicates models.
|
|
46
|
+
- "find model X" → use find-model instead.
|
|
47
|
+
- "score model X" → use model-score.
|
|
48
|
+
- "describe model X" → use model-info.
|
|
49
|
+
|
|
50
|
+
Negative Examples (should NOT call list-models)
|
|
51
|
+
- "find model churn" (find-model)
|
|
52
|
+
- "model info customerRisk" (model-info)
|
|
53
|
+
- "score model sales_pred" (model-score)
|
|
54
|
+
- "list jobs" (list-jobs)
|
|
55
|
+
|
|
56
|
+
Usage Tips
|
|
57
|
+
- Combine with findModel for narrowing down after a broad list.
|
|
58
|
+
- Increase limit judiciously; very large pages can impact latency.
|
|
59
|
+
|
|
60
|
+
Examples (→ mapped params)
|
|
61
|
+
- "list models" → { start:1, limit:10 }
|
|
62
|
+
- "list 25 models" → { start:1, limit:25 }
|
|
63
|
+
- "next models" (after prior {start:1,limit:10}) → { start:11, limit:10 }
|
|
64
|
+
`;
|
|
65
|
+
|
|
66
|
+
let spec = {
|
|
67
|
+
name: 'list-models',
|
|
68
|
+
aliases: ['listModels','list models','list_models'],
|
|
69
|
+
description: description,
|
|
70
|
+
schema: {
|
|
71
|
+
'limit': z.number().default(10),
|
|
72
|
+
'start': z.number().default(1)
|
|
73
|
+
},
|
|
74
|
+
handler: async (params) => {
|
|
75
|
+
let r = await _listModels(params);
|
|
76
|
+
return r;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return spec;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export default listModels;
|
|
@@ -0,0 +1,95 @@
|
|
|
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 debug from 'debug';
|
|
8
|
+
import _listTables from '../toolHelpers/_listTables.js';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
function listTables(_appContext) {
|
|
12
|
+
const log = debug('tools');
|
|
13
|
+
|
|
14
|
+
let description = `
|
|
15
|
+
## list-tables — enumerate tables within a specific CAS or SAS library
|
|
16
|
+
|
|
17
|
+
LLM Invocation Guidance (When to use)
|
|
18
|
+
Use THIS tool when the user explicitly wants the tables inside ONE library:
|
|
19
|
+
- "list tables in Samples"
|
|
20
|
+
- "show tables in sashelp"
|
|
21
|
+
- "list cas tables in Public"
|
|
22
|
+
- "list 25 tables in Samples"
|
|
23
|
+
- "next tables" (after a prior listTables call)
|
|
24
|
+
|
|
25
|
+
Do NOT use this tool to list the following
|
|
26
|
+
- lib -> use list-libraries
|
|
27
|
+
- list models -> use list-models
|
|
28
|
+
- list jobs -> use list-jobs
|
|
29
|
+
- list jobdefs -> use list-jobdefs
|
|
30
|
+
- Finding whether a library exists (use find-library)
|
|
31
|
+
- Describing a single table's columns or metadata (use table-info)
|
|
32
|
+
- Reading table data rows (use read-table)
|
|
33
|
+
- Listing jobs/models (other specialized tools)
|
|
34
|
+
|
|
35
|
+
Purpose
|
|
36
|
+
Return the names (and possibly lightweight metadata) of tables contained in a specified library (CAS caslib or SAS libref).
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
- lib (string, required): Library to inspect (e.g. "Samples", "sashelp").
|
|
40
|
+
- server (cas|sas, default 'cas'): Target environment; default when unspecified is CAS.
|
|
41
|
+
- limit (number, default 10): Page size.
|
|
42
|
+
- start (number, default 1): 1-based offset for pagination.
|
|
43
|
+
- where (string, optional): Filter expression (if supported by backend) or ignored safely.
|
|
44
|
+
|
|
45
|
+
Response Contract
|
|
46
|
+
- JSON: { tables: string[] [, start:number]? }
|
|
47
|
+
- tables array is empty when no matches.
|
|
48
|
+
- Include start = start + limit when length === limit (possible more pages).
|
|
49
|
+
|
|
50
|
+
Pagination Examples
|
|
51
|
+
- First page: { lib:'Samples', start:1, limit:10 }
|
|
52
|
+
- Next page: { lib:'Samples', start:11, limit:10 }
|
|
53
|
+
|
|
54
|
+
Disambiguation & Clarification
|
|
55
|
+
- Missing library name → ask: "Which library do you want to list tables from?"
|
|
56
|
+
- Input only "list tables" → ask for the library unless prior context supplies one.
|
|
57
|
+
- If user mentions multiple libs ("tables in Public and Samples") → request a single library.
|
|
58
|
+
|
|
59
|
+
Negative Examples (should NOT call list-tables)
|
|
60
|
+
- "list libs" (list-libraries)
|
|
61
|
+
- "find lib Public" (find-library)
|
|
62
|
+
- "describe table cars" (table-info)
|
|
63
|
+
- "read table cars from sashelp" (read-table)
|
|
64
|
+
|
|
65
|
+
Usage Tips
|
|
66
|
+
- After listing, call table-info to inspect structure or read-table for sample data.
|
|
67
|
+
- Keep limit moderate; page for very large libraries.
|
|
68
|
+
|
|
69
|
+
Examples (→ mapped params)
|
|
70
|
+
- "list tables in samples" → { lib:"samples", start:1, limit:10 }
|
|
71
|
+
- "show 25 tables in sashelp" → { lib:"sashelp", limit:25, start:1 }
|
|
72
|
+
- "next tables" (after previous {start:1,limit:10}) → { start:11, limit:10, lib:<previousLib> }
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
let spec = {
|
|
76
|
+
name: 'list-tables',
|
|
77
|
+
aliases: ['listTables','list tables','list_tables'],
|
|
78
|
+
description: description,
|
|
79
|
+
|
|
80
|
+
schema: {
|
|
81
|
+
'lib': z.string(),
|
|
82
|
+
'server': z.string().default('cas'),
|
|
83
|
+
'limit': z.number().default(10),
|
|
84
|
+
'start': z.number().default(1)
|
|
85
|
+
},
|
|
86
|
+
required: ['lib'],
|
|
87
|
+
handler: async (params) => {
|
|
88
|
+
let r = await _listTables(params);
|
|
89
|
+
return r;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return spec;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export default listTables;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import listModels from './listModels.js';
|
|
7
|
+
import listTables from './listTables.js';
|
|
8
|
+
import modelScore from './modelScore.js';
|
|
9
|
+
import modelInfo from './modelInfo.js';
|
|
10
|
+
import findLibrary from './findLibrary.js';
|
|
11
|
+
import readTable from './readTable.js';
|
|
12
|
+
import tableInfo from './tableInfo.js';
|
|
13
|
+
import listLibraries from './listLibraries.js';
|
|
14
|
+
|
|
15
|
+
import scrInfo from './scrInfo.js';
|
|
16
|
+
import scrScore from './scrScore.js';
|
|
17
|
+
|
|
18
|
+
import devaScore from './devaScore.js';
|
|
19
|
+
|
|
20
|
+
import findTable from './findTable.js';
|
|
21
|
+
import findModel from './findModel.js';
|
|
22
|
+
import runProgram from './runProgram.js';
|
|
23
|
+
import runMacro from './runMacro.js';
|
|
24
|
+
import runJob from './runJob.js';
|
|
25
|
+
import listJobs from './listJobs.js';
|
|
26
|
+
import runJobdef from './runJobdef.js';
|
|
27
|
+
import findJob from './findJob.js';
|
|
28
|
+
import listJobdefs from './listJobdefs.js';
|
|
29
|
+
import findJobdef from './findJobdef.js';
|
|
30
|
+
|
|
31
|
+
import sasQuery from './sasQuery.js';
|
|
32
|
+
import setContext from './setContext.js';
|
|
33
|
+
|
|
34
|
+
function makeTools(_appContext) {
|
|
35
|
+
// wrap all tools with
|
|
36
|
+
let customTools = [];
|
|
37
|
+
|
|
38
|
+
// get the tool definitions and handler
|
|
39
|
+
let list = [
|
|
40
|
+
listModels(_appContext),
|
|
41
|
+
|
|
42
|
+
findModel(_appContext),
|
|
43
|
+
modelInfo(_appContext),
|
|
44
|
+
modelScore(_appContext),
|
|
45
|
+
|
|
46
|
+
scrInfo(_appContext),
|
|
47
|
+
scrScore(_appContext),
|
|
48
|
+
|
|
49
|
+
findLibrary(_appContext),
|
|
50
|
+
listLibraries(_appContext),
|
|
51
|
+
findTable(_appContext),
|
|
52
|
+
tableInfo(_appContext),
|
|
53
|
+
listTables(_appContext),
|
|
54
|
+
readTable(_appContext),
|
|
55
|
+
sasQuery(_appContext),
|
|
56
|
+
|
|
57
|
+
runProgram(_appContext),
|
|
58
|
+
runMacro(_appContext),
|
|
59
|
+
|
|
60
|
+
findJob(_appContext),
|
|
61
|
+
listJobs(_appContext),
|
|
62
|
+
runJob(_appContext),
|
|
63
|
+
listJobdefs(_appContext),
|
|
64
|
+
findJobdef(_appContext),
|
|
65
|
+
runJobdef(_appContext),
|
|
66
|
+
|
|
67
|
+
devaScore(_appContext),
|
|
68
|
+
setContext(_appContext)
|
|
69
|
+
|
|
70
|
+
];
|
|
71
|
+
let listWithCustom = list.concat(customTools);
|
|
72
|
+
console.error(`\n[Note] Loaded a total of ${listWithCustom.length} tools.`);
|
|
73
|
+
return listWithCustom;
|
|
74
|
+
}
|
|
75
|
+
export default makeTools;
|
|
Binary file
|