@sassoftware/sas-score-mcp-serverjs 1.0.1-3 → 1.0.1-31
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/agents/sas-score-mcp-serverjs-agent.md +190 -0
- package/.skills/copilot-instructions.md +241 -0
- package/.skills/skills/README.md +125 -0
- package/.skills/skills/detail-strategy/SKILL.md +272 -0
- package/.skills/skills/find-resources/SKILL.md +155 -0
- package/.skills/skills/list-resource/SKILL.md +258 -0
- package/.skills/skills/read-strategy/SKILL.md +137 -0
- package/.skills/skills/request-routing/SKILL.md +107 -0
- package/.skills/skills/score-strategy/SKILL.md +231 -0
- package/README.md +96 -54
- package/cli.js +37 -27
- package/openApi.yaml +121 -121
- package/package.json +14 -14
- package/scripts/docs/oauth-http-transport.md +2 -2
- package/scripts/refreshtoken.js +58 -0
- package/src/createMcpServer.js +0 -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 +5 -1
- 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 +12 -7
- package/src/toolHelpers/_findJob.js +12 -0
- package/src/toolHelpers/_findJobdef.js +10 -0
- package/src/toolHelpers/_findLibrary.js +10 -0
- package/src/toolHelpers/_findModel.js +12 -0
- package/src/toolHelpers/_findTable.js +10 -0
- package/src/toolHelpers/_listJobs.js +2 -1
- package/src/toolHelpers/_listLibrary.js +1 -1
- package/src/toolHelpers/_listTables.js +1 -1
- package/src/toolHelpers/getLogonPayload.js +2 -2
- package/src/toolSet/devaScore.js +61 -61
- package/src/toolSet/findJob.js +2 -1
- package/src/toolSet/findJobdef.js +7 -7
- package/src/toolSet/findLibrary.js +68 -68
- package/src/toolSet/findModel.js +2 -2
- package/src/toolSet/findTable.js +2 -2
- package/src/toolSet/jobInfo.js +59 -0
- package/src/toolSet/jobdefInfo.js +59 -0
- package/src/toolSet/listJobdefs.js +61 -61
- package/src/toolSet/listJobs.js +61 -61
- package/src/toolSet/listLibraries.js +78 -78
- package/src/toolSet/listModels.js +56 -56
- package/src/toolSet/listTables.js +66 -66
- package/src/toolSet/makeTools.js +3 -0
- package/src/toolSet/modelInfo.js +1 -1
- package/src/toolSet/modelScore.js +23 -25
- package/src/toolSet/readTable.js +63 -63
- package/src/toolSet/runCasProgram.js +21 -10
- package/src/toolSet/runJob.js +15 -19
- package/src/toolSet/runJobdef.js +15 -19
- package/src/toolSet/runMacro.js +82 -82
- package/src/toolSet/sasQuery.js +77 -77
- package/src/toolSet/scrScore.js +60 -69
- package/src/toolSet/setContext.js +65 -65
- package/src/toolSet/superstat.js +61 -61
- package/src/toolSet/tableInfo.js +58 -58
- package/.skills_claude/README.md +0 -303
- package/.skills_claude/TESTING_GUIDE.md +0 -252
- package/.skills_claude/agents/sas-viya-scoring-expert.md +0 -58
- package/.skills_claude/claude-desktop-config.json +0 -16
- package/.skills_claude/claude-desktop-system-prompt.md +0 -127
- package/.skills_claude/copilot-instructions.md +0 -155
- package/.skills_claude/instructions.md +0 -184
- package/.skills_claude/skills/sas-find-library-smart/SKILL.md +0 -157
- package/.skills_claude/skills/sas-find-resource-strategy/SKILL.md +0 -105
- package/.skills_claude/skills/sas-list-resource-strategy/SKILL.md +0 -124
- package/.skills_claude/skills/sas-list-tables-smart/SKILL.md +0 -126
- package/.skills_claude/skills/sas-read-and-score/SKILL.md +0 -112
- package/.skills_claude/skills/sas-read-strategy/SKILL.md +0 -154
- package/.skills_claude/skills/sas-request-classifier/SKILL.md +0 -69
- package/.skills_claude/skills/sas-score-workflow/SKILL.md +0 -200
- package/.skills_claude/skills-index.md +0 -345
- package/.skills_github/agents/sas-viya-scoring-expert.md +0 -58
- package/.skills_github/copilot-instructions.md +0 -177
- package/.skills_github/skills/sas-find-library-smart/SKILL.md +0 -155
- package/.skills_github/skills/sas-find-resource-strategy/SKILL.md +0 -105
- package/.skills_github/skills/sas-list-resource-strategy/SKILL.md +0 -124
- package/.skills_github/skills/sas-list-tables-smart/SKILL.md +0 -128
- package/.skills_github/skills/sas-read-and-score/SKILL.md +0 -113
- package/.skills_github/skills/sas-read-strategy/SKILL.md +0 -154
- package/.skills_github/skills/sas-request-classifier/SKILL.md +0 -74
- package/.skills_github/skills/sas-score-workflow/SKILL.md +0 -314
- 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/.claude/settings.local.json +0 -13
|
@@ -44,7 +44,7 @@ async function _listTables(params) {
|
|
|
44
44
|
structuredContent: response};
|
|
45
45
|
} catch (err) {
|
|
46
46
|
console.error(JSON.stringify(err));
|
|
47
|
-
return {isError: true, content: [{ type: 'text', text: JSON.stringify(err) }] }
|
|
47
|
+
return {isError: true, content: [{ type: 'text', text: (typeof err === 'string') ? err : JSON.stringify(err) }] }
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
};
|
|
@@ -58,7 +58,7 @@ async function igetLogonPayload(_appContext) {
|
|
|
58
58
|
|
|
59
59
|
// Use user supplied refresh token-
|
|
60
60
|
if (_appContext.AUTHFLOW === "refresh") {
|
|
61
|
-
console.error("[Note] Using user supplied refresh token", _appContext.REFRESH_TOKEN);
|
|
61
|
+
console.error("[Note] Using user supplied refresh token", _appContext.REFRESH_TOKEN.substring(0,20) + "...");
|
|
62
62
|
let token = await refreshToken(_appContext,{token: _appContext.REFRESH_TOKEN, host: _appContext.VIYA_SERVER});
|
|
63
63
|
let logonPayload = {
|
|
64
64
|
host: _appContext.VIYA_SERVER,
|
|
@@ -71,7 +71,7 @@ async function igetLogonPayload(_appContext) {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
if (_appContext.AUTHFLOW === "token") {
|
|
74
|
-
console.error("[Note] Using token supplied by user");
|
|
74
|
+
console.error("[Note] Using token supplied by user");
|
|
75
75
|
let logonPayload = {
|
|
76
76
|
host: _appContext.VIYA_SERVER,
|
|
77
77
|
authType: "server",
|
package/src/toolSet/devaScore.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 { z } from 'zod';
|
|
6
|
-
|
|
7
|
-
function devaScore(_appContext) {
|
|
8
|
-
|
|
9
|
-
let description = `
|
|
10
|
-
deva-score — compute a numeric score based on two input values.
|
|
11
|
-
|
|
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
|
|
14
|
-
|
|
15
|
-
PARAMETERS
|
|
16
|
-
- a: number (required) — first input value
|
|
17
|
-
- b: number (required) — second input value
|
|
18
|
-
|
|
19
|
-
FORMULA: (a + b) * 42
|
|
20
|
-
|
|
21
|
-
ROUTING RULES
|
|
22
|
-
- "calculate deva score for 5 and 10" → { a: 5, b: 10 }
|
|
23
|
-
- "score 1 and 2" → { a: 1, b: 2 }
|
|
24
|
-
- "deva score a=3, b=7" → { a: 3, b: 7 }
|
|
25
|
-
- Multiple numbers → chain calls left-to-right: call(first, second), then call(result, third)
|
|
26
|
-
|
|
27
|
-
EXAMPLES
|
|
28
|
-
- "Calculate deva score for 5 and 10" → { a: 5, b: 10 } returns 630
|
|
29
|
-
- "Score 1 and 2" → { a: 1, b: 2 } returns 126
|
|
30
|
-
- "Deva score 20 and 30" → { a: 20, b: 30 } returns 2100
|
|
31
|
-
|
|
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)
|
|
36
|
-
|
|
37
|
-
RESPONSE
|
|
38
|
-
Returns { score: (a + b) * 42 }
|
|
39
|
-
`;
|
|
40
|
-
let spec = {
|
|
41
|
-
name: 'deva-score',
|
|
42
|
-
description: description,
|
|
43
|
-
inputSchema: z.object({
|
|
44
|
-
a: z.number(),
|
|
45
|
-
b: z.number(),
|
|
46
|
-
}),
|
|
47
|
-
handler: async ({ a, b }) => {
|
|
48
|
-
console.error(a, b);
|
|
49
|
-
let r = { score: (a + b) * 42 };
|
|
50
|
-
console.error('deva score result', r);
|
|
51
|
-
return {
|
|
52
|
-
content: [{ type: 'text', text: 'deva score result: ' + JSON.stringify(r) }],
|
|
53
|
-
structuredContent: r
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return spec;
|
|
59
|
-
}
|
|
60
|
-
export default devaScore;
|
|
61
|
-
|
|
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
|
+
|
|
7
|
+
function devaScore(_appContext) {
|
|
8
|
+
|
|
9
|
+
let description = `
|
|
10
|
+
deva-score — compute a numeric score based on two input values.
|
|
11
|
+
|
|
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
|
|
14
|
+
|
|
15
|
+
PARAMETERS
|
|
16
|
+
- a: number (required) — first input value
|
|
17
|
+
- b: number (required) — second input value
|
|
18
|
+
|
|
19
|
+
FORMULA: (a + b) * 42
|
|
20
|
+
|
|
21
|
+
ROUTING RULES
|
|
22
|
+
- "calculate deva score for 5 and 10" → { a: 5, b: 10 }
|
|
23
|
+
- "score 1 and 2" → { a: 1, b: 2 }
|
|
24
|
+
- "deva score a=3, b=7" → { a: 3, b: 7 }
|
|
25
|
+
- Multiple numbers → chain calls left-to-right: call(first, second), then call(result, third)
|
|
26
|
+
|
|
27
|
+
EXAMPLES
|
|
28
|
+
- "Calculate deva score for 5 and 10" → { a: 5, b: 10 } returns 630
|
|
29
|
+
- "Score 1 and 2" → { a: 1, b: 2 } returns 126
|
|
30
|
+
- "Deva score 20 and 30" → { a: 20, b: 30 } returns 2100
|
|
31
|
+
|
|
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)
|
|
36
|
+
|
|
37
|
+
RESPONSE
|
|
38
|
+
Returns { score: (a + b) * 42 }
|
|
39
|
+
`;
|
|
40
|
+
let spec = {
|
|
41
|
+
name: 'deva-score',
|
|
42
|
+
description: description,
|
|
43
|
+
inputSchema: z.object({
|
|
44
|
+
a: z.number(),
|
|
45
|
+
b: z.number(),
|
|
46
|
+
}),
|
|
47
|
+
handler: async ({ a, b }) => {
|
|
48
|
+
console.error(a, b);
|
|
49
|
+
let r = { score: (a + b) * 42 };
|
|
50
|
+
console.error('deva score result', r);
|
|
51
|
+
return {
|
|
52
|
+
content: [{ type: 'text', text: 'deva score result: ' + JSON.stringify(r) }],
|
|
53
|
+
structuredContent: r
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return spec;
|
|
59
|
+
}
|
|
60
|
+
export default devaScore;
|
|
61
|
+
|
package/src/toolSet/findJob.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
import _listJobs from '../toolHelpers/_listJobs.js';
|
|
7
|
+
import _findJob from '../toolHelpers/_findJob.js';
|
|
7
8
|
function findJob(_appContext) {
|
|
8
9
|
|
|
9
10
|
let description = `
|
|
@@ -45,7 +46,7 @@ Returns { jobs: [] } if not found; { jobs: [name, ...] } if found. Never halluci
|
|
|
45
46
|
name: z.string()
|
|
46
47
|
}),
|
|
47
48
|
handler: async (params) => {
|
|
48
|
-
let r = await
|
|
49
|
+
let r = await _findJob(params);
|
|
49
50
|
return r;
|
|
50
51
|
}
|
|
51
52
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
import
|
|
6
|
+
import _findJobdeg from '../toolHelpers/_findJobdef.js';
|
|
7
7
|
function findJobdef(_appContext) {
|
|
8
8
|
let llmDescription= {
|
|
9
9
|
"purpose": "Map natural language requests to find a jobdef (job definition) in SAS Viya and return structured results.",
|
|
@@ -18,7 +18,7 @@ function findJobdef(_appContext) {
|
|
|
18
18
|
find-jobdef — locate a specific SAS Viya job definition.
|
|
19
19
|
|
|
20
20
|
USE when: find jobdef, does jobdef exist, is there a jobdef named, lookup jobdef, verify jobdef exists
|
|
21
|
-
DO NOT USE for: list jobdefs (use list-jobdefs), run jobdef (use run-jobdef), find job/lib/table/model (use respective tools)
|
|
21
|
+
DO NOT USE for: list jobdefs (use sas-score-list-jobdefs), run jobdef (use sas-score-run-jobdef), find job/lib/table/model (use respective tools)
|
|
22
22
|
|
|
23
23
|
PARAMETERS
|
|
24
24
|
- name: string (required) — jobdef name to locate; if multiple supplied, use first
|
|
@@ -38,10 +38,10 @@ EXAMPLES
|
|
|
38
38
|
- "is there a jobdef named metricsRefresh" → { name: "metricsRefresh" }
|
|
39
39
|
|
|
40
40
|
NEGATIVE EXAMPLES (do not route here)
|
|
41
|
-
- "list jobdefs" (use list-jobdefs)
|
|
42
|
-
- "run jobdef cars_job_v4" (use run-jobdef)
|
|
43
|
-
- "find job ETL" (use find-job)
|
|
44
|
-
- "find table cars" (use find-table)
|
|
41
|
+
- "list jobdefs" (use sas-score-list-jobdefs)
|
|
42
|
+
- "run jobdef cars_job_v4" (use sas-score-run-jobdef)
|
|
43
|
+
- "find job ETL" (use sas-score-find-job)
|
|
44
|
+
- "find table cars" (use sas-score-find-table)
|
|
45
45
|
|
|
46
46
|
ERRORS
|
|
47
47
|
Returns { jobdefs: [] } if not found; { jobdefs: [name, ...] } if found. Never hallucinate jobdef names.
|
|
@@ -54,7 +54,7 @@ Returns { jobdefs: [] } if not found; { jobdefs: [name, ...] } if found. Never h
|
|
|
54
54
|
name: z.string()
|
|
55
55
|
}),
|
|
56
56
|
handler: async (params) => {
|
|
57
|
-
let r = await
|
|
57
|
+
let r = await _findJobdef(params);
|
|
58
58
|
return r;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -1,68 +1,68 @@
|
|
|
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 findLibrary(_appContext) {
|
|
8
|
-
|
|
9
|
-
let description = `
|
|
10
|
-
find-library — locate a specific CAS or SAS library.
|
|
11
|
-
|
|
12
|
-
USE when: find library, find lib, does library exist, is library available, lookup library
|
|
13
|
-
DO NOT USE for: list libraries (use list-libraries), find table/job/jobdef/model (use respective tools), table structure (use table-info), create library (use run-sas-program)
|
|
14
|
-
|
|
15
|
-
PARAMETERS
|
|
16
|
-
- name: string (required) — library/caslib name; if multiple supplied, use first
|
|
17
|
-
- server: 'cas' | 'sas' (default: 'cas') — target environment
|
|
18
|
-
|
|
19
|
-
ROUTING RULES
|
|
20
|
-
- "find lib <name>" → { name: "<name>", server: "cas" }
|
|
21
|
-
- "find lib <name> in cas" → { name: "<name>", server: "cas" }
|
|
22
|
-
- "find library <name> in sas" → { name: "<name>", server: "sas" }
|
|
23
|
-
- "does library <name> exist" → { name: "<name>", server: "cas" }
|
|
24
|
-
- "find lib" with no name → ask "Which library name would you like to find?"
|
|
25
|
-
- "list libraries / list libs" → use list-libraries instead
|
|
26
|
-
- "tables in <lib>" → use list-tables instead
|
|
27
|
-
|
|
28
|
-
EXAMPLES
|
|
29
|
-
- "find lib Public" → { name: "Public", server: "cas" }
|
|
30
|
-
- "find library sasuser in sas" → { name: "sasuser", server: "sas" }
|
|
31
|
-
- "does library Formats exist" → { name: "Formats", server: "cas" }
|
|
32
|
-
|
|
33
|
-
NEGATIVE EXAMPLES (do not route here)
|
|
34
|
-
- "list libs" (use list-libraries)
|
|
35
|
-
- "show tables in Public" (use list-tables)
|
|
36
|
-
- "find table cars in sashelp" (use find-table)
|
|
37
|
-
- "find job cars_job" (use find-job)
|
|
38
|
-
|
|
39
|
-
ERRORS
|
|
40
|
-
Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Never hallucinate library names.
|
|
41
|
-
`;
|
|
42
|
-
|
|
43
|
-
let spec = {
|
|
44
|
-
name: 'find-library',
|
|
45
|
-
description: description,
|
|
46
|
-
inputSchema: z.object({
|
|
47
|
-
name: z.string(),
|
|
48
|
-
server: z.string().optional()
|
|
49
|
-
}),
|
|
50
|
-
|
|
51
|
-
handler: async (params) => {
|
|
52
|
-
// normalize server to lowercase & default
|
|
53
|
-
if (!params.server) params.server = 'cas';
|
|
54
|
-
params.server = params.server.toLowerCase();
|
|
55
|
-
|
|
56
|
-
// If multiple names passed (comma or space separated), take the first token (defensive)
|
|
57
|
-
if (params.name && /[,\s]+/.test(params.name.trim())) {
|
|
58
|
-
params.name = params.name.split(/[,\s]+/).filter(Boolean)[0];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
let r = await _listLibrary(params);
|
|
62
|
-
return r;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return spec;
|
|
66
|
-
}
|
|
67
|
-
export default findLibrary;
|
|
68
|
-
|
|
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 findLibrary(_appContext) {
|
|
8
|
+
|
|
9
|
+
let description = `
|
|
10
|
+
find-library — locate a specific CAS or SAS library.
|
|
11
|
+
|
|
12
|
+
USE when: find library, find lib, does library exist, is library available, lookup library
|
|
13
|
+
DO NOT USE for: list libraries (use list-libraries), find table/job/jobdef/model (use respective tools), table structure (use table-info), create library (use run-sas-program)
|
|
14
|
+
|
|
15
|
+
PARAMETERS
|
|
16
|
+
- name: string (required) — library/caslib name; if multiple supplied, use first
|
|
17
|
+
- server: 'cas' | 'sas' (default: 'cas') — target environment
|
|
18
|
+
|
|
19
|
+
ROUTING RULES
|
|
20
|
+
- "find lib <name>" → { name: "<name>", server: "cas" }
|
|
21
|
+
- "find lib <name> in cas" → { name: "<name>", server: "cas" }
|
|
22
|
+
- "find library <name> in sas" → { name: "<name>", server: "sas" }
|
|
23
|
+
- "does library <name> exist" → { name: "<name>", server: "cas" }
|
|
24
|
+
- "find lib" with no name → ask "Which library name would you like to find?"
|
|
25
|
+
- "list libraries / list libs" → use list-libraries instead
|
|
26
|
+
- "tables in <lib>" → use list-tables instead
|
|
27
|
+
|
|
28
|
+
EXAMPLES
|
|
29
|
+
- "find lib Public" → { name: "Public", server: "cas" }
|
|
30
|
+
- "find library sasuser in sas" → { name: "sasuser", server: "sas" }
|
|
31
|
+
- "does library Formats exist" → { name: "Formats", server: "cas" }
|
|
32
|
+
|
|
33
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
34
|
+
- "list libs" (use list-libraries)
|
|
35
|
+
- "show tables in Public" (use list-tables)
|
|
36
|
+
- "find table cars in sashelp" (use find-table)
|
|
37
|
+
- "find job cars_job" (use find-job)
|
|
38
|
+
|
|
39
|
+
ERRORS
|
|
40
|
+
Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Never hallucinate library names.
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
let spec = {
|
|
44
|
+
name: 'find-library',
|
|
45
|
+
description: description,
|
|
46
|
+
inputSchema: z.object({
|
|
47
|
+
name: z.string(),
|
|
48
|
+
server: z.string().optional()
|
|
49
|
+
}),
|
|
50
|
+
|
|
51
|
+
handler: async (params) => {
|
|
52
|
+
// normalize server to lowercase & default
|
|
53
|
+
if (!params.server) params.server = 'cas';
|
|
54
|
+
params.server = params.server.toLowerCase();
|
|
55
|
+
|
|
56
|
+
// If multiple names passed (comma or space separated), take the first token (defensive)
|
|
57
|
+
if (params.name && /[,\s]+/.test(params.name.trim())) {
|
|
58
|
+
params.name = params.name.split(/[,\s]+/).filter(Boolean)[0];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let r = await _listLibrary(params);
|
|
62
|
+
return r;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return spec;
|
|
66
|
+
}
|
|
67
|
+
export default findLibrary;
|
|
68
|
+
|
package/src/toolSet/findModel.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
-
import
|
|
7
|
+
import _findModel from '../toolHelpers/_findModel.js';
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
function findModel(_appContext) {
|
|
@@ -49,7 +49,7 @@ Returns { models: [] } if not found; { models: [name, ...] } if found. Never hal
|
|
|
49
49
|
name: z.string()
|
|
50
50
|
}),
|
|
51
51
|
handler: async (params) => {
|
|
52
|
-
let r = await
|
|
52
|
+
let r = await _findModel(params);
|
|
53
53
|
return r;
|
|
54
54
|
}
|
|
55
55
|
}
|
package/src/toolSet/findTable.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
//import debug from 'debug';
|
|
8
|
-
import
|
|
8
|
+
import _findTable from '../toolHelpers/_findTable.js';
|
|
9
9
|
|
|
10
10
|
function findTable(_appContext) {
|
|
11
11
|
let description = `
|
|
@@ -54,7 +54,7 @@ Returns { tables: [] } if not found; { tables: [name, ...] } if found. Never hal
|
|
|
54
54
|
|
|
55
55
|
handler: async (params) => {
|
|
56
56
|
// Check if the params.scenario is a string and parse it
|
|
57
|
-
let r = await
|
|
57
|
+
let r = await _findTable(params);
|
|
58
58
|
return r;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
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 jobInfo(_appContext) {
|
|
8
|
+
|
|
9
|
+
let description = `
|
|
10
|
+
job-info — return information about a specific SAS Viya job.
|
|
11
|
+
|
|
12
|
+
USE when: find job, does job exist, is there a job named, lookup job, verify job exists
|
|
13
|
+
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
|
+
|
|
15
|
+
PARAMETERS
|
|
16
|
+
- name: string (required) — name of job whose details are being requested. Should be exact match to job name.
|
|
17
|
+
|
|
18
|
+
ROUTING RULES
|
|
19
|
+
- "describe job <name>" → { name: "<name>" }
|
|
20
|
+
- "describe model <name.job>"
|
|
21
|
+
- "info for job <name>" → { name: "<name>" }
|
|
22
|
+
|
|
23
|
+
EXAMPLES
|
|
24
|
+
- "describe job cars_job_v4" → { name: "cars_job_v4" }
|
|
25
|
+
|
|
26
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
27
|
+
- "list jobs" (use list-jobs)
|
|
28
|
+
- "run job cars_job_v4" (use run-job)
|
|
29
|
+
- "execute jobdef cars_job_v4" (use run-jobdef)
|
|
30
|
+
|
|
31
|
+
ERRORS
|
|
32
|
+
Returns job metadata
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
let spec = {
|
|
36
|
+
name: 'job-info',
|
|
37
|
+
description: description,
|
|
38
|
+
inputSchema: z.object({
|
|
39
|
+
name: z.string()
|
|
40
|
+
}),
|
|
41
|
+
handler: async (params) => {
|
|
42
|
+
if (params.name != null) {
|
|
43
|
+
if (params.name.endsWith('.job')) {
|
|
44
|
+
params.name = params.name.slice(0, -4);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// _listJobs can handle job lookup by name and will return an appropriate error message if not found, so we can rely on that for error handling here.
|
|
48
|
+
let r = await _listJobs(params);
|
|
49
|
+
return r;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
/* correct spec for registerTool with inputSchema */
|
|
55
|
+
|
|
56
|
+
return spec;
|
|
57
|
+
}
|
|
58
|
+
export default jobInfo;
|
|
59
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
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 jobdefInfo(_appContext) {
|
|
8
|
+
|
|
9
|
+
let description = `
|
|
10
|
+
jobdef -info — return information about a specific SAS Viya jobdef.
|
|
11
|
+
|
|
12
|
+
USE when: find jobdef, does jobdef exist, is there a jobdef named, lookup jobdef, verify jobdef exists
|
|
13
|
+
DO NOT USE for: list jobdefs (use list-jobdefs), run jobdef (use run-jobdef), find lib/table/model (use respective tools)
|
|
14
|
+
|
|
15
|
+
PARAMETERS
|
|
16
|
+
- name: string (required) — name of jobdef whose details are being requested. Should be exact match to jobdef name.
|
|
17
|
+
|
|
18
|
+
ROUTING RULES
|
|
19
|
+
- "describe jobdef <name>" → { name: "<name>" }
|
|
20
|
+
- "describe model <name.jobdef>"
|
|
21
|
+
- "info for jobdef <name>" → { name: "<name>" }
|
|
22
|
+
|
|
23
|
+
EXAMPLES
|
|
24
|
+
- "describe jobdef cars_job_v4" → { name: "cars_job_v4" }
|
|
25
|
+
|
|
26
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
27
|
+
- "list jobdefs" (use list-jobdefs)
|
|
28
|
+
- "run jobdef cars_job_v4" (use run-jobdef)
|
|
29
|
+
- "execute jobdef cars_job_v4" (use run-jobdef)
|
|
30
|
+
|
|
31
|
+
ERRORS
|
|
32
|
+
Returns job metadata
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
let spec = {
|
|
36
|
+
name: 'jobdef-info',
|
|
37
|
+
description: description,
|
|
38
|
+
inputSchema: z.object({
|
|
39
|
+
name: z.string()
|
|
40
|
+
}),
|
|
41
|
+
handler: async (params) => {
|
|
42
|
+
if (params.name != null) {
|
|
43
|
+
if (params.name.endsWith('.jobdef')) {
|
|
44
|
+
params.name = params.name.slice(0, -7);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// _listJobs can handle job lookup by name and will return an appropriate error message if not found, so we can rely on that for error handling here.
|
|
48
|
+
let r = await _listJobdefs(params);
|
|
49
|
+
return r;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
/* correct spec for registerTool with inputSchema */
|
|
55
|
+
|
|
56
|
+
return spec;
|
|
57
|
+
}
|
|
58
|
+
export default jobdefInfo;
|
|
59
|
+
|
|
@@ -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 { 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 (jobdefs) assets.
|
|
11
|
-
|
|
12
|
-
USE when: list jobdefs, show jobdefs, browse jobdefs, list available jobdefs, next page
|
|
13
|
-
DO NOT USE for: find single jobdef (use find-jobdef), execute jobdef (use run-jobdef), find job (use find-job), sas code (use run-sas-program)
|
|
14
|
-
|
|
15
|
-
PARAMETERS
|
|
16
|
-
- limit: number (default: 10) — number of jobdefs per page
|
|
17
|
-
- start: number (default: 1) — 1-based page offset
|
|
18
|
-
- where: string (default: '') — optional filter expression
|
|
19
|
-
|
|
20
|
-
ROUTING RULES
|
|
21
|
-
- list jobdefs → { start: 1, limit: 10 }
|
|
22
|
-
- show me 25 jobdefs → { start: 1, limit: 25 }
|
|
23
|
-
- next jobdefs → { start: previousStart + previousLimit, limit: previousLimit }
|
|
24
|
-
|
|
25
|
-
EXAMPLES
|
|
26
|
-
- list jobdefs → { start: 1, limit: 10 }
|
|
27
|
-
- list 25 jobdefs → { start: 1, limit: 25 }
|
|
28
|
-
- next jobdefs → { start: 11, limit: 10 }
|
|
29
|
-
|
|
30
|
-
NEGATIVE EXAMPLES (do not route here)
|
|
31
|
-
- find jobdef abc (use find-jobdef)
|
|
32
|
-
- list jobs (use list-jobs)
|
|
33
|
-
- run jobdef abc (use run-jobdef)
|
|
34
|
-
- list models (use list-models)
|
|
35
|
-
|
|
36
|
-
PAGINATION
|
|
37
|
-
If returned length === limit, hint: next start = start + limit. Empty result with start > 1 means paged past end.
|
|
38
|
-
|
|
39
|
-
ERRORS
|
|
40
|
-
Surface backend error directly; never fabricate jobdef names.
|
|
41
|
-
`;
|
|
42
|
-
|
|
43
|
-
let spec = {
|
|
44
|
-
name: 'list-jobdefs',
|
|
45
|
-
description: description,
|
|
46
|
-
inputSchema: z.object({
|
|
47
|
-
limit: z.number().optional(),
|
|
48
|
-
start: z.number().optional(),
|
|
49
|
-
where: z.string().optional()
|
|
50
|
-
}),
|
|
51
|
-
// No 'server' required; backend context is implicit in helper
|
|
52
|
-
handler: async (params) => {
|
|
53
|
-
// _listJobdefs handles all validation and defaults
|
|
54
|
-
const result = await _listJobdefs(params);
|
|
55
|
-
return result;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return spec;
|
|
59
|
-
}
|
|
60
|
-
export default listJobdefs;
|
|
61
|
-
|
|
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 (jobdefs) assets.
|
|
11
|
+
|
|
12
|
+
USE when: list jobdefs, show jobdefs, browse jobdefs, list available jobdefs, next page
|
|
13
|
+
DO NOT USE for: find single jobdef (use find-jobdef), execute jobdef (use run-jobdef), find job (use find-job), sas code (use run-sas-program)
|
|
14
|
+
|
|
15
|
+
PARAMETERS
|
|
16
|
+
- limit: number (default: 10) — number of jobdefs per page
|
|
17
|
+
- start: number (default: 1) — 1-based page offset
|
|
18
|
+
- where: string (default: '') — optional filter expression
|
|
19
|
+
|
|
20
|
+
ROUTING RULES
|
|
21
|
+
- list jobdefs → { start: 1, limit: 10 }
|
|
22
|
+
- show me 25 jobdefs → { start: 1, limit: 25 }
|
|
23
|
+
- next jobdefs → { start: previousStart + previousLimit, limit: previousLimit }
|
|
24
|
+
|
|
25
|
+
EXAMPLES
|
|
26
|
+
- list jobdefs → { start: 1, limit: 10 }
|
|
27
|
+
- list 25 jobdefs → { start: 1, limit: 25 }
|
|
28
|
+
- next jobdefs → { start: 11, limit: 10 }
|
|
29
|
+
|
|
30
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
31
|
+
- find jobdef abc (use find-jobdef)
|
|
32
|
+
- list jobs (use list-jobs)
|
|
33
|
+
- run jobdef abc (use run-jobdef)
|
|
34
|
+
- list models (use list-models)
|
|
35
|
+
|
|
36
|
+
PAGINATION
|
|
37
|
+
If returned length === limit, hint: next start = start + limit. Empty result with start > 1 means paged past end.
|
|
38
|
+
|
|
39
|
+
ERRORS
|
|
40
|
+
Surface backend error directly; never fabricate jobdef names.
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
let spec = {
|
|
44
|
+
name: 'list-jobdefs',
|
|
45
|
+
description: description,
|
|
46
|
+
inputSchema: z.object({
|
|
47
|
+
limit: z.number().optional(),
|
|
48
|
+
start: z.number().optional(),
|
|
49
|
+
where: z.string().optional()
|
|
50
|
+
}),
|
|
51
|
+
// No 'server' required; backend context is implicit in helper
|
|
52
|
+
handler: async (params) => {
|
|
53
|
+
// _listJobdefs handles all validation and defaults
|
|
54
|
+
const result = await _listJobdefs(params);
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return spec;
|
|
59
|
+
}
|
|
60
|
+
export default listJobdefs;
|
|
61
|
+
|