@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/openApi.yaml
CHANGED
|
@@ -1,121 +1,121 @@
|
|
|
1
|
-
swagger: "2.0"
|
|
2
|
-
info:
|
|
3
|
-
title: SAS Viya Sample MCP Server API
|
|
4
|
-
version: "1.0.0"
|
|
5
|
-
description: API for interacting with the SAS Viya Sample MCP Server.
|
|
6
|
-
host: localhost:8080
|
|
7
|
-
basePath: /
|
|
8
|
-
schemes:
|
|
9
|
-
- http
|
|
10
|
-
- https
|
|
11
|
-
consumes:
|
|
12
|
-
- application/json
|
|
13
|
-
produces:
|
|
14
|
-
- application/json
|
|
15
|
-
paths:
|
|
16
|
-
/health:
|
|
17
|
-
get:
|
|
18
|
-
summary: Health check
|
|
19
|
-
description: Returns health and version information.
|
|
20
|
-
responses:
|
|
21
|
-
200:
|
|
22
|
-
description: Health information
|
|
23
|
-
schema:
|
|
24
|
-
type: object
|
|
25
|
-
properties:
|
|
26
|
-
name:
|
|
27
|
-
type: string
|
|
28
|
-
version:
|
|
29
|
-
type: string
|
|
30
|
-
description:
|
|
31
|
-
type: string
|
|
32
|
-
endpoints:
|
|
33
|
-
type: object
|
|
34
|
-
usage:
|
|
35
|
-
type: string
|
|
36
|
-
/apiMeta:
|
|
37
|
-
get:
|
|
38
|
-
summary: API metadata
|
|
39
|
-
description: Returns the OpenAPI specification for this server.
|
|
40
|
-
responses:
|
|
41
|
-
200:
|
|
42
|
-
description: OpenAPI document
|
|
43
|
-
schema:
|
|
44
|
-
type: object
|
|
45
|
-
/mcp:
|
|
46
|
-
options:
|
|
47
|
-
summary: CORS preflight
|
|
48
|
-
description: CORS preflight endpoint.
|
|
49
|
-
responses:
|
|
50
|
-
204:
|
|
51
|
-
description: No Content
|
|
52
|
-
post:
|
|
53
|
-
summary: MCP request
|
|
54
|
-
description: Handles MCP JSON-RPC requests.
|
|
55
|
-
parameters:
|
|
56
|
-
- name: body
|
|
57
|
-
in: body
|
|
58
|
-
required: true
|
|
59
|
-
schema:
|
|
60
|
-
type: object
|
|
61
|
-
- name: Authorization
|
|
62
|
-
in: header
|
|
63
|
-
required: false
|
|
64
|
-
type: string
|
|
65
|
-
description: Bearer token for authentication
|
|
66
|
-
- name: X-VIYA-SERVER
|
|
67
|
-
in: header
|
|
68
|
-
required: false
|
|
69
|
-
type: string
|
|
70
|
-
description: Override VIYA server
|
|
71
|
-
- name: X-REFRESH-TOKEN
|
|
72
|
-
in: header
|
|
73
|
-
required: false
|
|
74
|
-
type: string
|
|
75
|
-
description: Refresh token for authentication
|
|
76
|
-
- name: mcp-session-id
|
|
77
|
-
in: header
|
|
78
|
-
required: false
|
|
79
|
-
type: string
|
|
80
|
-
description: Session ID
|
|
81
|
-
responses:
|
|
82
|
-
200:
|
|
83
|
-
description: MCP response
|
|
84
|
-
schema:
|
|
85
|
-
type: object
|
|
86
|
-
500:
|
|
87
|
-
description: Server error
|
|
88
|
-
schema:
|
|
89
|
-
type: object
|
|
90
|
-
get:
|
|
91
|
-
summary: Get MCP session
|
|
92
|
-
description: Retrieves information for an MCP session.
|
|
93
|
-
parameters:
|
|
94
|
-
- name: mcp-session-id
|
|
95
|
-
in: header
|
|
96
|
-
required: true
|
|
97
|
-
type: string
|
|
98
|
-
description: Session ID
|
|
99
|
-
responses:
|
|
100
|
-
200:
|
|
101
|
-
description: Session information
|
|
102
|
-
schema:
|
|
103
|
-
type: object
|
|
104
|
-
400:
|
|
105
|
-
description: Invalid or missing session ID
|
|
106
|
-
delete:
|
|
107
|
-
summary: Delete MCP session
|
|
108
|
-
description: Deletes an MCP session.
|
|
109
|
-
parameters:
|
|
110
|
-
- name: mcp-session-id
|
|
111
|
-
in: header
|
|
112
|
-
required: true
|
|
113
|
-
type: string
|
|
114
|
-
description: Session ID
|
|
115
|
-
responses:
|
|
116
|
-
200:
|
|
117
|
-
description: Session deleted
|
|
118
|
-
schema:
|
|
119
|
-
type: object
|
|
120
|
-
400:
|
|
121
|
-
description: Invalid or missing session ID
|
|
1
|
+
swagger: "2.0"
|
|
2
|
+
info:
|
|
3
|
+
title: SAS Viya Sample MCP Server API
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
description: API for interacting with the SAS Viya Sample MCP Server.
|
|
6
|
+
host: localhost:8080
|
|
7
|
+
basePath: /
|
|
8
|
+
schemes:
|
|
9
|
+
- http
|
|
10
|
+
- https
|
|
11
|
+
consumes:
|
|
12
|
+
- application/json
|
|
13
|
+
produces:
|
|
14
|
+
- application/json
|
|
15
|
+
paths:
|
|
16
|
+
/health:
|
|
17
|
+
get:
|
|
18
|
+
summary: Health check
|
|
19
|
+
description: Returns health and version information.
|
|
20
|
+
responses:
|
|
21
|
+
200:
|
|
22
|
+
description: Health information
|
|
23
|
+
schema:
|
|
24
|
+
type: object
|
|
25
|
+
properties:
|
|
26
|
+
name:
|
|
27
|
+
type: string
|
|
28
|
+
version:
|
|
29
|
+
type: string
|
|
30
|
+
description:
|
|
31
|
+
type: string
|
|
32
|
+
endpoints:
|
|
33
|
+
type: object
|
|
34
|
+
usage:
|
|
35
|
+
type: string
|
|
36
|
+
/apiMeta:
|
|
37
|
+
get:
|
|
38
|
+
summary: API metadata
|
|
39
|
+
description: Returns the OpenAPI specification for this server.
|
|
40
|
+
responses:
|
|
41
|
+
200:
|
|
42
|
+
description: OpenAPI document
|
|
43
|
+
schema:
|
|
44
|
+
type: object
|
|
45
|
+
/mcp:
|
|
46
|
+
options:
|
|
47
|
+
summary: CORS preflight
|
|
48
|
+
description: CORS preflight endpoint.
|
|
49
|
+
responses:
|
|
50
|
+
204:
|
|
51
|
+
description: No Content
|
|
52
|
+
post:
|
|
53
|
+
summary: MCP request
|
|
54
|
+
description: Handles MCP JSON-RPC requests.
|
|
55
|
+
parameters:
|
|
56
|
+
- name: body
|
|
57
|
+
in: body
|
|
58
|
+
required: true
|
|
59
|
+
schema:
|
|
60
|
+
type: object
|
|
61
|
+
- name: Authorization
|
|
62
|
+
in: header
|
|
63
|
+
required: false
|
|
64
|
+
type: string
|
|
65
|
+
description: Bearer token for authentication
|
|
66
|
+
- name: X-VIYA-SERVER
|
|
67
|
+
in: header
|
|
68
|
+
required: false
|
|
69
|
+
type: string
|
|
70
|
+
description: Override VIYA server
|
|
71
|
+
- name: X-REFRESH-TOKEN
|
|
72
|
+
in: header
|
|
73
|
+
required: false
|
|
74
|
+
type: string
|
|
75
|
+
description: Refresh token for authentication
|
|
76
|
+
- name: mcp-session-id
|
|
77
|
+
in: header
|
|
78
|
+
required: false
|
|
79
|
+
type: string
|
|
80
|
+
description: Session ID
|
|
81
|
+
responses:
|
|
82
|
+
200:
|
|
83
|
+
description: MCP response
|
|
84
|
+
schema:
|
|
85
|
+
type: object
|
|
86
|
+
500:
|
|
87
|
+
description: Server error
|
|
88
|
+
schema:
|
|
89
|
+
type: object
|
|
90
|
+
get:
|
|
91
|
+
summary: Get MCP session
|
|
92
|
+
description: Retrieves information for an MCP session.
|
|
93
|
+
parameters:
|
|
94
|
+
- name: mcp-session-id
|
|
95
|
+
in: header
|
|
96
|
+
required: true
|
|
97
|
+
type: string
|
|
98
|
+
description: Session ID
|
|
99
|
+
responses:
|
|
100
|
+
200:
|
|
101
|
+
description: Session information
|
|
102
|
+
schema:
|
|
103
|
+
type: object
|
|
104
|
+
400:
|
|
105
|
+
description: Invalid or missing session ID
|
|
106
|
+
delete:
|
|
107
|
+
summary: Delete MCP session
|
|
108
|
+
description: Deletes an MCP session.
|
|
109
|
+
parameters:
|
|
110
|
+
- name: mcp-session-id
|
|
111
|
+
in: header
|
|
112
|
+
required: true
|
|
113
|
+
type: string
|
|
114
|
+
description: Session ID
|
|
115
|
+
responses:
|
|
116
|
+
200:
|
|
117
|
+
description: Session deleted
|
|
118
|
+
schema:
|
|
119
|
+
type: object
|
|
120
|
+
400:
|
|
121
|
+
description: Invalid or missing session ID
|
package/src/processHeaders.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { start } from "node:repl";
|
|
2
|
-
|
|
3
1
|
/*
|
|
4
2
|
* Copyright © 2026, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
5
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
@@ -32,20 +30,25 @@ function processHeaders(req, res, next, cache, appContext) {
|
|
|
32
30
|
const hdr = req.header("Authorization");
|
|
33
31
|
//for now, ignore Authorization if authflow is not bearer
|
|
34
32
|
let token = (hdr != null) ? hdr.slice(7) : null;
|
|
35
|
-
//console.error("[Note] Authorization token", token);
|
|
36
33
|
debugger;
|
|
37
|
-
console.error('
|
|
34
|
+
console.error('[Note} AUTHFLOW=', appContext.AUTHFLOW);
|
|
35
|
+
console.error("[Note] External authorization :", appContext.AUTHEXTERNAL);
|
|
38
36
|
if (appContext.AUTHFLOW === 'bearer') {
|
|
39
37
|
debugger;
|
|
40
38
|
let startAuth = false;
|
|
41
|
-
|
|
39
|
+
|
|
42
40
|
if (appContext.AUTHEXTERNAL === true) {
|
|
43
41
|
console.error("[Note] Expecting external authorization");
|
|
44
42
|
if (token != null) {
|
|
45
43
|
console.error("[Note] Using user supplied token for authorization");
|
|
46
44
|
headerCache.bearerToken = token;
|
|
47
45
|
} else {
|
|
48
|
-
|
|
46
|
+
console.error("[Note] No Authorization token provided in header for external authorization.");
|
|
47
|
+
console.error("[Note] Returning 404 since we are configured for external token and no token provided in header.");
|
|
48
|
+
return res.status(404).json({
|
|
49
|
+
error: "unauthorized",
|
|
50
|
+
error_description: "[Error] Missing token for external authorization."
|
|
51
|
+
});
|
|
49
52
|
}
|
|
50
53
|
} else if (token == null) {
|
|
51
54
|
console.error("[Note] No Authorization token provided in header.");
|
|
@@ -55,7 +58,7 @@ function processHeaders(req, res, next, cache, appContext) {
|
|
|
55
58
|
let tokenlist = cache.get("tokenlist");
|
|
56
59
|
let tokenData = tokenlist[token];
|
|
57
60
|
if (tokenData == null) {
|
|
58
|
-
return res.status(
|
|
61
|
+
return res.status(401).json({
|
|
59
62
|
error: "unauthorized",
|
|
60
63
|
error_description: "[Error] Expired token. Clear token and try again."
|
|
61
64
|
});
|
package/src/setupSkills.js
CHANGED
|
@@ -19,7 +19,7 @@ function setupSkills(clientName,agentFolder) {
|
|
|
19
19
|
if (agentFolder) {
|
|
20
20
|
destination = path.join(destination, agentFolder);
|
|
21
21
|
}
|
|
22
|
-
const source = path.join(__dirname, `../.skills`
|
|
22
|
+
const source = path.join(__dirname, `../.skills`);
|
|
23
23
|
console.error("==================================================================");
|
|
24
24
|
console.error(` Copying ${source} to ${destination}...`);
|
|
25
25
|
|
|
@@ -28,22 +28,19 @@ function setupSkills(clientName,agentFolder) {
|
|
|
28
28
|
if (!fs.existsSync(to)) fs.mkdirSync(to, { recursive: true });;
|
|
29
29
|
fs.readdirSync(from).forEach(element => {
|
|
30
30
|
const fromPath = path.join(from, element);
|
|
31
|
-
|
|
31
|
+
let toPath = path.join(to, element);
|
|
32
|
+
if (clientName === 'claude' && element === 'copilot-instructions.md') {
|
|
33
|
+
toPath = path.join(to, 'CLAUDE.md');
|
|
34
|
+
}
|
|
32
35
|
if (fs.lstatSync(fromPath).isFile()) {
|
|
33
36
|
console.error(` 📄 Copying file: ${element}`);
|
|
34
37
|
fs.copyFileSync(fromPath, toPath);
|
|
35
38
|
} else if (fs.lstatSync(fromPath).isDirectory()) {
|
|
36
39
|
console.error(`📂 Copying folder: ${element}`);
|
|
37
|
-
copyFolderSync(fromPath, toPath)
|
|
40
|
+
copyFolderSync(fromPath, toPath);
|
|
38
41
|
}
|
|
39
42
|
});
|
|
40
43
|
}
|
|
41
|
-
|
|
42
|
-
// now copy the skills folder to the destination
|
|
43
|
-
let toPath = path.join(destination, '.skills');
|
|
44
|
-
let fromPath = path.join(__dirname, `../.skills`);
|
|
45
|
-
copyFolderSync(fromPath, toPath);
|
|
46
|
-
|
|
47
44
|
function listExpandedFolder(dir, indent = "") {
|
|
48
45
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
49
46
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import restaflib from '@sassoftware/restaflib';
|
|
7
|
+
import restaf from '@sassoftware/restaf';
|
|
8
|
+
async function _casScore(params) {
|
|
9
|
+
let { model, name, scenario, _appContext } = params;
|
|
10
|
+
let { casSetup, caslScore } = restaflib;
|
|
11
|
+
|
|
12
|
+
let store = restaf.initStore(_appContext.storeConfig);
|
|
13
|
+
let { session } = await casSetup(store, _appContext.logonPayload, null, _appContext.cas);
|
|
14
|
+
if (session == null) {
|
|
15
|
+
return { content: [{ type: 'text', text: 'Could not create a cas session' }] };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
let args = {
|
|
20
|
+
name: name,
|
|
21
|
+
modelName: model,
|
|
22
|
+
scenario: scenario
|
|
23
|
+
}
|
|
24
|
+
let output = await caslScore(store, session, args);
|
|
25
|
+
let results = output.casResults;
|
|
26
|
+
return { content: [{ type: 'text', text: JSON.stringify(results) }], structuredContent: results };
|
|
27
|
+
} catch (err) {
|
|
28
|
+
console.log(err);
|
|
29
|
+
return { isError: true, content: [{ type: 'text', text: JSON.stringify(err) }] };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export default _casScore;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Return lean description in agent mode, full description in standalone mode.
|
|
8
|
+
* @param {object} appContext - the _appContext passed to every tool factory
|
|
9
|
+
* @param {string} lean - short description for agent mode (~3-6 lines)
|
|
10
|
+
* @param {string} full - full description for standalone mode
|
|
11
|
+
*/
|
|
12
|
+
export function desc(appContext, lean, full) {
|
|
13
|
+
return (appContext && appContext.agent) ? lean : full;
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import _listJobs from './_listJobs.js';
|
|
7
|
+
async function _findJob(params) {
|
|
8
|
+
let r = await _listJobs(params);
|
|
9
|
+
console.error ("findJob result:" , r);
|
|
10
|
+
return r;
|
|
11
|
+
}
|
|
12
|
+
export default _findJob;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import _listJobdefs from './_listJobdefs.js';
|
|
7
|
+
async function _findJobdef(params) {
|
|
8
|
+
return await _listJobdefs(params);
|
|
9
|
+
}
|
|
10
|
+
export default _findJobdef;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import _listLibrary from './_listLibrary.js';
|
|
7
|
+
async function _findLibrary(params) {
|
|
8
|
+
params.tool = 'find';
|
|
9
|
+
return await _listLibrary(params);
|
|
10
|
+
}
|
|
11
|
+
export default _findLibrary;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import _listMas from './_listMas.js';
|
|
7
|
+
async function _findMas(params) {
|
|
8
|
+
params.tool = 'find';
|
|
9
|
+
let r = await _listMas(params);
|
|
10
|
+
console.log ("findMas result:" , r);
|
|
11
|
+
return r;
|
|
12
|
+
}
|
|
13
|
+
export default _findMas;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import axios from 'axios';
|
|
7
|
+
|
|
8
|
+
async function _findScr(params) {
|
|
9
|
+
let {name} = params;
|
|
10
|
+
let config = {
|
|
11
|
+
method: 'HEAD',
|
|
12
|
+
name: name + '/apiMeta/api',
|
|
13
|
+
headers: {
|
|
14
|
+
'Accept': 'application/json'
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
console.error('[Note] Config:', config);
|
|
19
|
+
let response = await axios(config);
|
|
20
|
+
console.error('[Note] Response status:', response.status);
|
|
21
|
+
if (response.status !== 200) {
|
|
22
|
+
|
|
23
|
+
return {isError: true, content: [{ type: 'text', text: `SCR model ${name} not found` }]};
|
|
24
|
+
} else if (response.status === 200) {
|
|
25
|
+
let r = { scr: [name] };
|
|
26
|
+
return { content: [{ type: 'text', text: JSON.stringify(r) }],
|
|
27
|
+
structuredOutput: r
|
|
28
|
+
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
return {isError: true,content: [{ type: 'text', text: JSON.stringify(error) }]};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export default _findScr;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import _listTables from './_listTables.js';
|
|
7
|
+
async function _findTable(params) {
|
|
8
|
+
params.tool = 'find';
|
|
9
|
+
return await _listTables(params);
|
|
10
|
+
}
|
|
11
|
+
export default _findTable;
|
|
@@ -6,7 +6,7 @@ import restaf from '@sassoftware/restaf';
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
async function _listJobdefs(params) {
|
|
9
|
-
let { limit, start, name, _appContext } = params;
|
|
9
|
+
let { limit, start, name, tool, _appContext } = params;
|
|
10
10
|
|
|
11
11
|
let store = restaf.initStore(_appContext.storeConfig);
|
|
12
12
|
let msg = await store.logon(_appContext.logonPayload);
|
|
@@ -41,7 +41,17 @@ async function _listJobdefs(params) {
|
|
|
41
41
|
|
|
42
42
|
let response = {jobDefinitions: Object.keys(names)};
|
|
43
43
|
if (name != null) {
|
|
44
|
-
|
|
44
|
+
if (tool === 'find') {
|
|
45
|
+
response = { job: [name] };
|
|
46
|
+
} else if (tool === 'describe') {
|
|
47
|
+
let p = [];
|
|
48
|
+
names[name].parameters.map((v, k) => {
|
|
49
|
+
if (v.name.startsWith('_') === false) {
|
|
50
|
+
p.push(v);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
response = { describe: p };
|
|
54
|
+
};
|
|
45
55
|
}
|
|
46
56
|
|
|
47
57
|
return {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import restaf from '@sassoftware/restaf';
|
|
7
7
|
|
|
8
8
|
async function _listJobs(params) {
|
|
9
|
-
let { limit, start, name, _appContext } = params;
|
|
9
|
+
let { limit, start, name, tool, _appContext } = params;
|
|
10
10
|
|
|
11
11
|
let store = restaf.initStore(_appContext.storeConfig);
|
|
12
12
|
let msg = await store.logon(_appContext.logonPayload);
|
|
@@ -33,21 +33,32 @@ async function _listJobs(params) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
let names = {};
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
jobList.itemsList().map((id, n) => {
|
|
38
38
|
let jname = jobList.items(id, 'data', 'jobRequest', 'name');
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
if (names[jname] == null) {
|
|
41
41
|
let value = jobList.items(id, 'data', 'jobRequest', 'jobDefinition', 'parameters');
|
|
42
|
-
names[jname] = {parameters: (value == null) ? {} : value.toJS() };
|
|
42
|
+
names[jname] = { parameters: (value == null) ? {} : value.toJS() };
|
|
43
43
|
}
|
|
44
44
|
});
|
|
45
|
-
|
|
46
|
-
let response
|
|
45
|
+
console.error('parameters', JSON.stringify(names, null, 2));
|
|
46
|
+
let response = { jobs: Object.keys(names) };
|
|
47
|
+
console.error('response', JSON.stringify(response, null, 2));
|
|
47
48
|
|
|
48
49
|
if (name != null) {
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
if (tool === 'find') {
|
|
51
|
+
response = { job: [name] };
|
|
52
|
+
} else if (tool === 'describe') {
|
|
53
|
+
let p = [];
|
|
54
|
+
names[name].parameters.map((v, k) => {
|
|
55
|
+
if (v.name.startsWith('_') === false) {
|
|
56
|
+
p.push(v);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
response = { describe: p };
|
|
60
|
+
};
|
|
61
|
+
}
|
|
51
62
|
return {
|
|
52
63
|
content: [{ type: 'text', text: JSON.stringify(response) }],
|
|
53
64
|
structuredContent: response,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import restaf from '@sassoftware/restaf';
|
|
7
7
|
|
|
8
|
-
async function
|
|
8
|
+
async function _listMas(params) {
|
|
9
9
|
let { limit, start , name, _appContext} = params;;
|
|
10
10
|
// setup
|
|
11
11
|
|
|
@@ -27,9 +27,9 @@ async function _listModels(params) {
|
|
|
27
27
|
}
|
|
28
28
|
let result = await store.apiCall(microanalyticScore.links('modules'), payload);
|
|
29
29
|
if (result.itemsList().size === 0) {
|
|
30
|
-
return { content: [{ type: 'text', text: `No
|
|
30
|
+
return { content: [{ type: 'text', text: `No MAS exist in MAS server` }]};
|
|
31
31
|
}
|
|
32
|
-
let list = {
|
|
32
|
+
let list = {mas: result.itemsList().toJS()};
|
|
33
33
|
return { content: [{ type: 'text', text: JSON.stringify(list) }],
|
|
34
34
|
structuredContent: list
|
|
35
35
|
};
|
|
@@ -38,4 +38,4 @@ async function _listModels(params) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
export default
|
|
41
|
+
export default _listMas;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
async function _listScr(params) {
|
|
7
|
+
let response = { scr: [] };
|
|
8
|
+
return {
|
|
9
|
+
content: [{ type: 'text', text: JSON.stringify(response) }],
|
|
10
|
+
structuredContent: response
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export default _listScr;
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
import axios from 'axios';
|
|
7
7
|
|
|
8
|
-
async function
|
|
9
|
-
let {
|
|
8
|
+
async function _scrDescribe(params) {
|
|
9
|
+
let {name} = params;
|
|
10
10
|
let config = {
|
|
11
11
|
method: 'GET',
|
|
12
|
-
|
|
12
|
+
name: name + '/apiMeta/api',
|
|
13
13
|
headers: {
|
|
14
14
|
'Accept': 'application/json'
|
|
15
15
|
}
|
|
@@ -29,4 +29,4 @@ async function _scrInfo(params) {
|
|
|
29
29
|
return {isError: true,content: [{ type: 'text', text: JSON.stringify(error) }]};
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
export default
|
|
32
|
+
export default _scrDescribe;
|
|
@@ -7,7 +7,7 @@ import axios from 'axios';
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
async function _scrScore(params) {
|
|
10
|
-
let {
|
|
10
|
+
let { name, scenario} = params;
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
let data = scenario.split(',').reduce((acc, pair) => {
|
|
@@ -18,7 +18,7 @@ async function _scrScore(params) {
|
|
|
18
18
|
|
|
19
19
|
let config = {
|
|
20
20
|
method: 'POST',
|
|
21
|
-
|
|
21
|
+
name: name,
|
|
22
22
|
headers: {
|
|
23
23
|
'Content-Type': 'application/json',
|
|
24
24
|
'Accept': 'application/json'
|