@sassoftware/sas-score-mcp-serverjs 1.0.1-9 → 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 +11 -13
- package/openApi.yaml +121 -121
- package/package.json +16 -14
- 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 +1 -18
- 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/.agents/sas-score-mcp-serverjs-agent.md +0 -58
- package/.instructions/copilot-instructions.md +0 -201
- package/.instructions/enforce-find-resource-strategy.md +0 -35
- 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/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
|
@@ -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'
|
|
@@ -2,33 +2,35 @@
|
|
|
2
2
|
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
|
+
import restaf from '@sassoftware/restaf';
|
|
5
6
|
import restaflib from '@sassoftware/restaflib';
|
|
6
7
|
|
|
7
8
|
async function _submitCasl(params) {
|
|
8
9
|
let { src, args, _appContext } = params;
|
|
10
|
+
let { casSetup, caslRun } = restaflib;
|
|
11
|
+
console.error(_appContext);
|
|
12
|
+
let store = restaf.initStore(_appContext.storeConfig);
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
let session = await restaflib.casSetup(store, _appContext.logonPayload, null, _appContext.cas);
|
|
14
|
+
let { session } = await casSetup(store, _appContext.logonPayload, null, _appContext.cas);
|
|
13
15
|
if (session == null) {
|
|
14
|
-
return {content: [{ type: 'text', text: 'Could not create a cas session' }]};
|
|
16
|
+
return { content: [{ type: 'text', text: 'Could not create a cas session' }] };
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
try {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
catch (err) {
|
|
20
|
+
console.error(caslRun);
|
|
21
|
+
debugger;
|
|
22
|
+
let r = await caslRun(store, session, src, (args == null) ? {} : args);
|
|
23
|
+
console.error(r.results);
|
|
24
|
+
let response = (r.results == null) ? r : r.results;
|
|
25
|
+
await store.apiCall(session.links('delete'));
|
|
26
|
+
return { content: [{ type: 'text', text: JSON.stringify(response) }], structuredContent: response };
|
|
27
|
+
} catch (err) {
|
|
29
28
|
console.error(err);
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
if (session != null) {
|
|
30
|
+
await store.apiCall(session.links('delete'));
|
|
31
|
+
}
|
|
32
|
+
return { isError: true, content: [{ type: 'text', text: JSON.stringify(err) }] };
|
|
32
33
|
}
|
|
33
34
|
}
|
|
35
|
+
|
|
34
36
|
export default _submitCasl;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import restafedit from '@sassoftware/restafedit';
|
|
6
6
|
import deleteSession from './deleteSession.js';
|
|
7
7
|
|
|
8
|
-
async function
|
|
8
|
+
async function _tableDescribe(params) {
|
|
9
9
|
let { table, lib, server, _appContext } = params;
|
|
10
10
|
|
|
11
11
|
|
|
@@ -69,4 +69,4 @@ async function _tableInfo(params) {
|
|
|
69
69
|
return { isError: true, content: [{ type: 'text', text: JSON.stringify(err) }] };
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
export default
|
|
72
|
+
export default _tableDescribe;
|
|
@@ -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",
|
|
@@ -0,0 +1,93 @@
|
|
|
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 _casScore from '../toolHelpers/_casScore.js';
|
|
8
|
+
|
|
9
|
+
function casModelScore(_appContext) {
|
|
10
|
+
const isAgent = _appContext && _appContext.agent;
|
|
11
|
+
|
|
12
|
+
let description = isAgent ? `
|
|
13
|
+
cas-model-score — score with a model persisted as a CAS table in a CAS server.
|
|
14
|
+
PARAMS: name(string, required), model(string, optional),scenario (string|object, optional)
|
|
15
|
+
RETURNS: returns the score for the specified scenario
|
|
16
|
+
Notes: name is specified as a.b.cas where a is the library, b is the CAS table name, and .cas is the suffix. Model parameter is optional and can be used to specify a different model name if it is not the same as the table name.
|
|
17
|
+
` : `
|
|
18
|
+
cas-model-score — execute a CAS model on SAS Viya cas server.
|
|
19
|
+
|
|
20
|
+
USE when: score cas model with scenario
|
|
21
|
+
DO NOT USE for: macros (use ${_appContext.brand}-macro-score), SAS code (use ${_appContext.brand}-program-score), jobs (use ${_appContext.brand}-job-score), jobdefs (use ${_appContext.brand}-jobdef-score), scr(use ${_appContext.brand}-scr-score)
|
|
22
|
+
|
|
23
|
+
PARAMETERS
|
|
24
|
+
|
|
25
|
+
- name: string (optional) — CAS model table to use for scoring
|
|
26
|
+
- model: string (optional) — name of the model to use for scoring, if different from the table name
|
|
27
|
+
- scenario: string or object (optional) — input parameters
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
ROUTING RULES
|
|
31
|
+
- "score "mymodel.abc.cas" with scenario "x=1, y=2" → { name: "mymodel.abc", scenario: "x=1, y=2" }
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
EXAMPLES
|
|
35
|
+
- "score "mymodel.abc.cas" with scenario "x=1, y=2" → { name: "mymodel.abc", scenario: "x=1, y=2" }
|
|
36
|
+
|
|
37
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
38
|
+
- "score sas macro" (use ${_appContext.brand}-macro-score)
|
|
39
|
+
- "submit sas code" (use ${_appContext.brand}-program-score)
|
|
40
|
+
- "score job X" (use ${_appContext.brand}-job-score)
|
|
41
|
+
- "score jobdef X" (use ${_appContext.brand}-jobdef-score)
|
|
42
|
+
- "score scr X" (use ${_appContext.brand}-scr-score)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
RESPONSE
|
|
48
|
+
Log output and CAS results. If output table is specified, that table's rows up to the limit.
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
let spec = {
|
|
52
|
+
name: 'cas-model-score',
|
|
53
|
+
description: description,
|
|
54
|
+
inputSchema: z.object({
|
|
55
|
+
scenario: z.any().optional(),
|
|
56
|
+
model: z.string().optional(),
|
|
57
|
+
name: z.string()
|
|
58
|
+
}),
|
|
59
|
+
handler: async (params) => {
|
|
60
|
+
let {name, model, scenario, _appContext} = params;
|
|
61
|
+
// figure out src
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
// Convert the scenario string to an object
|
|
65
|
+
// Example: "x=1, y=2, z=3" to { x: 1, y: 2, z: 3 }
|
|
66
|
+
let scenarioObj = {};
|
|
67
|
+
if (typeof scenario === 'object' && scenario !== null) {
|
|
68
|
+
scenarioObj = scenario;
|
|
69
|
+
} else if (Array.isArray(scenario)) {
|
|
70
|
+
scenarioObj = scenario[0];
|
|
71
|
+
} else if (typeof scenario === 'string' && scenario.includes('=')) {
|
|
72
|
+
scenarioObj = scenario.split(',').reduce((acc, pair) => {
|
|
73
|
+
let [key, value] = pair.split('=');
|
|
74
|
+
acc[key.trim()] = value;
|
|
75
|
+
return acc;
|
|
76
|
+
}, {});
|
|
77
|
+
}
|
|
78
|
+
params.scenario = scenarioObj;
|
|
79
|
+
|
|
80
|
+
let iparms = {
|
|
81
|
+
args: scenarioObj,
|
|
82
|
+
model: params.model,
|
|
83
|
+
name: params.name,
|
|
84
|
+
_appContext: _appContext
|
|
85
|
+
}
|
|
86
|
+
let r = await _casScore(iparms);
|
|
87
|
+
return r;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return spec;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export default casModelScore;
|
|
@@ -0,0 +1,105 @@
|
|
|
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 _submitCasl from '../toolHelpers/_submitCasl.js';
|
|
8
|
+
import _casScore from '../toolHelpers/_casScore.js';
|
|
9
|
+
|
|
10
|
+
function casProgramScore(_appContext) {
|
|
11
|
+
const isAgent = _appContext && _appContext.agent;
|
|
12
|
+
|
|
13
|
+
let description = isAgent ? `
|
|
14
|
+
cas-program-score — execute a CAS program src code or score a persisted CAS model on SAS Viya server.
|
|
15
|
+
PARAMS: src (string, required), model(string,optional), name(string, optional),scenario (string|object, optional), output (string, optional), limit (number, optional)
|
|
16
|
+
RETURNS: log output and CAS results, optional output table rows
|
|
17
|
+
` : `
|
|
18
|
+
cas-program-score — execute a CAS program model on SAS Viya server.
|
|
19
|
+
|
|
20
|
+
USE when: score cas program, run cas program, submit CASL, score cas model with scenario
|
|
21
|
+
DO NOT USE for: macros (use ${_appContext.brand}-macro-score), SAS code (use ${_appContext.brand}-program-score), jobs (use ${_appContext.brand}-job-score), jobdefs (use ${_appContext.brand}-jobdef-score), scr(use ${_appContext.brand}-scr-score)
|
|
22
|
+
|
|
23
|
+
PARAMETERS
|
|
24
|
+
- src: string (required) — CAS program or CASL code to execute verbatim
|
|
25
|
+
- casmodel: string (optional) — CAS model table to use for scoring
|
|
26
|
+
- name: string (optional) — name of the model to use for scoring, if different from the table name
|
|
27
|
+
- scenario: string or object (optional) — input parameters
|
|
28
|
+
- output: string — table name to return in response
|
|
29
|
+
- limit: number (default: 100) — max rows to return
|
|
30
|
+
|
|
31
|
+
**NOTE** if both src and casmodel are specified, the casmodel will take precedence
|
|
32
|
+
ROUTING RULES
|
|
33
|
+
- "run cas program "action echo" → { src: "action echo" }
|
|
34
|
+
- "execute cas "action simple.summary" with table=a.b → { src: "action simple.summary",scenario: {
|
|
35
|
+
table: "a.b"} }
|
|
36
|
+
- "score casmodel "mymodel.abc" with scenario "x=1, y=2" → { casmodel: "mymodel.abc", scenario: "x=1, y=2" }
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
EXAMPLES
|
|
40
|
+
- "run cas program "action echo" → { src: "action echo" }
|
|
41
|
+
- "score casmodel "mymodel.abc" with scenario "x=1, y=2" → { casmodel: "mymodel.abc", scenario: "x=1, y=2" }
|
|
42
|
+
|
|
43
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
44
|
+
- "score sas macro" (use ${_appContext.brand}-macro-score)
|
|
45
|
+
- "submit sas code" (use ${_appContext.brand}-program-score)
|
|
46
|
+
- "score job X" (use ${_appContext.brand}-job-score)
|
|
47
|
+
- "score jobdef X" (use ${_appContext.brand}-jobdef-score)
|
|
48
|
+
- "score scr X" (use ${_appContext.brand}-scr-score)
|
|
49
|
+
|
|
50
|
+
NOTES
|
|
51
|
+
Sends src verbatim without validation. Use parameter scenario to pass arguments. For arbitrary SAS code use ${_appContext.brand}-program-score.
|
|
52
|
+
|
|
53
|
+
RESPONSE
|
|
54
|
+
Log output and CAS results. If output table is specified, that table's rows up to the limit.
|
|
55
|
+
`;
|
|
56
|
+
|
|
57
|
+
let spec = {
|
|
58
|
+
name: 'cas-program-score',
|
|
59
|
+
description: description,
|
|
60
|
+
inputSchema: z.object({
|
|
61
|
+
src: z.string(),
|
|
62
|
+
scenario: z.any().optional(),
|
|
63
|
+
output: z.string().optional(),
|
|
64
|
+
casmodel: z.string().optional(),
|
|
65
|
+
name: z.string().optional(),
|
|
66
|
+
limit: z.number().optional()
|
|
67
|
+
}),
|
|
68
|
+
handler: async (params) => {
|
|
69
|
+
let {src, scenario, _appContext} = params;
|
|
70
|
+
// figure out src
|
|
71
|
+
let isrc = src;
|
|
72
|
+
|
|
73
|
+
// Convert the scenario string to an object
|
|
74
|
+
// Example: "x=1, y=2, z=3" to { x: 1, y: 2, z: 3 }
|
|
75
|
+
let scenarioObj = {};
|
|
76
|
+
if (typeof scenario === 'object' && scenario !== null) {
|
|
77
|
+
scenarioObj = scenario;
|
|
78
|
+
} else if (Array.isArray(scenario)) {
|
|
79
|
+
scenarioObj = scenario[0];
|
|
80
|
+
} else if (typeof scenario === 'string' && scenario.includes('=')) {
|
|
81
|
+
scenarioObj = scenario.split(',').reduce((acc, pair) => {
|
|
82
|
+
let [key, value] = pair.split('=');
|
|
83
|
+
acc[key.trim()] = value;
|
|
84
|
+
return acc;
|
|
85
|
+
}, {});
|
|
86
|
+
}
|
|
87
|
+
params.scenario = scenarioObj;
|
|
88
|
+
|
|
89
|
+
let iparms = {
|
|
90
|
+
args: scenarioObj,
|
|
91
|
+
output: params.output,
|
|
92
|
+
limit: params.limit,
|
|
93
|
+
src: isrc,
|
|
94
|
+
model: params.casmodel,
|
|
95
|
+
name: params.name,
|
|
96
|
+
_appContext: _appContext
|
|
97
|
+
}
|
|
98
|
+
let r = (params.casmodel == null) ? await _submitCasl(iparms) : await _casScore(iparms);
|
|
99
|
+
return r;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return spec;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export default casProgramScore;
|
package/src/toolSet/devaScore.js
CHANGED
|
@@ -5,12 +5,17 @@
|
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
|
|
7
7
|
function devaScore(_appContext) {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
const isAgent = _appContext && _appContext.agent;
|
|
9
|
+
let brand = _appContext.brand + '-';
|
|
10
|
+
let description = isAgent ? `
|
|
11
|
+
deva-score — run a demonstration scoring calculation.
|
|
12
|
+
PARAMS: a (number, required), b (number, required)
|
|
13
|
+
RETURNS: computed result for a and b
|
|
14
|
+
` : `
|
|
10
15
|
deva-score — compute a numeric score based on two input values.
|
|
11
16
|
|
|
12
17
|
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
|
|
18
|
+
DO NOT USE for: model scoring (use ${brand}model-score), statistical calculations, data lookup
|
|
14
19
|
|
|
15
20
|
PARAMETERS
|
|
16
21
|
- a: number (required) — first input value
|
|
@@ -30,9 +35,9 @@ EXAMPLES
|
|
|
30
35
|
- "Deva score 20 and 30" → { a: 20, b: 30 } returns 2100
|
|
31
36
|
|
|
32
37
|
NEGATIVE EXAMPLES (do not route here)
|
|
33
|
-
- "Score this customer with credit model" (use model-score)
|
|
34
|
-
- "Calculate the mean of these values" (use
|
|
35
|
-
- "Statistical analysis of numbers" (use sas-query)
|
|
38
|
+
- "Score this customer with credit model" (use ${brand}model-score)
|
|
39
|
+
- "Calculate the mean of these values" (use ${brand}program-score or ${brand}sas-query)
|
|
40
|
+
- "Statistical analysis of numbers" (use ${brand}sas-query)
|
|
36
41
|
|
|
37
42
|
RESPONSE
|
|
38
43
|
Returns { score: (a + b) * 42 }
|