@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
|
@@ -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 }
|
package/src/toolSet/findJob.js
CHANGED
|
@@ -1,59 +1,74 @@
|
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- "
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- "find job
|
|
29
|
-
- "does job
|
|
30
|
-
- "is there a job named
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- "list jobs"
|
|
34
|
-
- "
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
+
import _findJob from '../toolHelpers/_findJob.js';
|
|
8
|
+
function findJob(_appContext) {
|
|
9
|
+
const isAgent = _appContext && _appContext.agent;
|
|
10
|
+
let description = isAgent ? `
|
|
11
|
+
find-job — verify a Job model exists.
|
|
12
|
+
PARAMS: name (string, required)
|
|
13
|
+
RETURNS: job metadata if found, error if not found
|
|
14
|
+
` : `
|
|
15
|
+
find-job — locate a specific SAS Viya job.
|
|
16
|
+
|
|
17
|
+
USE when: find job, does job exist, is there a job named, lookup job, verify job exists
|
|
18
|
+
DO NOT USE for: list jobs (use ${_appContext.brand}-list-jobs), score job (use ${_appContext.brand}-job-score), score jobdef (use ${_appContext.brand}-jobdef-score), find lib/table/model (use respective tools)
|
|
19
|
+
|
|
20
|
+
PARAMETERS
|
|
21
|
+
- name: string (required) — job name to locate; if multiple supplied, use first
|
|
22
|
+
|
|
23
|
+
Naming Rules:
|
|
24
|
+
- If user provides name with "job" suffix ".job", strip the suffix (e.g., "cars_job_v4.job"), and look for "cars_job_v4".
|
|
25
|
+
|
|
26
|
+
ROUTING RULES
|
|
27
|
+
- "find job <name>" → { name: "<name>" }
|
|
28
|
+
- "find name.job" → { name: "<name>" }
|
|
29
|
+
- "does job <name> exist" → { name: "<name>" }
|
|
30
|
+
- "is there a job named <name>" → { name: "<name>" }
|
|
31
|
+
- "lookup/verify job <name>" → { name: "<name>" }
|
|
32
|
+
- "find job" with no name → ask "Which job name would you like to find?"
|
|
33
|
+
- "find all jobs / list jobs" → use ${_appContext.brand}-list-jobs instead
|
|
34
|
+
- "score job <name>" → use ${_appContext.brand}-job-score instead
|
|
35
|
+
|
|
36
|
+
EXAMPLES
|
|
37
|
+
- "find job cars_job_v4" → { name: "cars_job_v4" }
|
|
38
|
+
- "does job ETL exist" → { name: "ETL" }
|
|
39
|
+
- "is there a job named metricsRefresh" → { name: "metricsRefresh" }
|
|
40
|
+
|
|
41
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
42
|
+
- "list jobs" (use ${_appContext.brand}-list-jobs)
|
|
43
|
+
- "score job cars_job_v4" (use ${_appContext.brand}-job-score)
|
|
44
|
+
- "score jobdef cars_job_v4" (use ${_appContext.brand}-jobdef-score)
|
|
45
|
+
|
|
46
|
+
ERRORS
|
|
47
|
+
Returns { jobs: [] } if not found; { jobs: [name, ...] } if found. Never hallucinate job names.
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
let spec = {
|
|
51
|
+
name: 'find-job',
|
|
52
|
+
description: description,
|
|
53
|
+
inputSchema: z.object({
|
|
54
|
+
name: z.string()
|
|
55
|
+
}),
|
|
56
|
+
handler: async (params) => {
|
|
57
|
+
if (params.name != null) {
|
|
58
|
+
if (params.name.endsWith('.job')) {
|
|
59
|
+
params.name = params.name.slice(0, -4);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
params.tool = 'find';
|
|
63
|
+
let r = await _findJob(params);
|
|
64
|
+
return r;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
/* correct spec for registerTool with inputSchema */
|
|
70
|
+
|
|
71
|
+
return spec;
|
|
72
|
+
}
|
|
73
|
+
export default findJob;
|
|
74
|
+
|
|
@@ -1,64 +1,67 @@
|
|
|
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
|
|
7
|
-
function findJobdef(_appContext) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- name
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- "
|
|
28
|
-
- "
|
|
29
|
-
- "
|
|
30
|
-
- "
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- "
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- "
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
- "
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
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 _findJobdef from '../toolHelpers/_findJobdef.js';
|
|
7
|
+
function findJobdef(_appContext) {
|
|
8
|
+
const isAgent = _appContext && _appContext.agent;
|
|
9
|
+
let description = isAgent ? `
|
|
10
|
+
find-jobdef — verify a JobDef model exists.
|
|
11
|
+
PARAMS: name (string, required)
|
|
12
|
+
RETURNS: jobdef metadata if found, error if not found
|
|
13
|
+
` : `
|
|
14
|
+
find-jobdef — locate a specific SAS Viya job definition.
|
|
15
|
+
|
|
16
|
+
USE when: find jobdef, does jobdef exist, is there a jobdef named, lookup jobdef, verify jobdef exists
|
|
17
|
+
DO NOT USE for: list jobdefs (use ${_appContext.brand}-list-jobdefs), score jobdef (use ${_appContext.brand}-jobdef-score), find job/lib/table/model (use respective tools)
|
|
18
|
+
|
|
19
|
+
PARAMETERS
|
|
20
|
+
- name: string (required) — jobdef name to locate; if multiple supplied, use first
|
|
21
|
+
|
|
22
|
+
ROUTING RULES
|
|
23
|
+
- "find jobdef <name>" → { name: "<name>" }
|
|
24
|
+
- "find name.jobdef" → { name: "<name>" }
|
|
25
|
+
- "does jobdef <name> exist" → { name: "<name>" }
|
|
26
|
+
- "is there a jobdef named <name>" → { name: "<name>" }
|
|
27
|
+
- "lookup/verify jobdef <name>" → { name: "<name>" }
|
|
28
|
+
- "find jobdef" with no name → ask "Which jobdef name would you like to find?"
|
|
29
|
+
- "find all jobdefs / list jobdefs" → use ${_appContext.brand}-list-jobdefs instead
|
|
30
|
+
- "score jobdef <name>" → use ${_appContext.brand}-jobdef-score instead
|
|
31
|
+
|
|
32
|
+
EXAMPLES
|
|
33
|
+
- "find jobdef cars_job_v4" → { name: "cars_job_v4" }
|
|
34
|
+
- "does jobdef ETL exist" → { name: "ETL" }
|
|
35
|
+
- "is there a jobdef named metricsRefresh" → { name: "metricsRefresh" }
|
|
36
|
+
|
|
37
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
38
|
+
- "list jobdefs" (use ${_appContext.brand}-list-jobdefs)
|
|
39
|
+
- "score jobdef cars_job_v4" (use ${_appContext.brand}-jobdef-score)
|
|
40
|
+
- "find job ETL" (use ${_appContext.brand}-find-job)
|
|
41
|
+
- "find table cars" (use ${_appContext.brand}-find-table)
|
|
42
|
+
|
|
43
|
+
ERRORS
|
|
44
|
+
Returns { jobdefs: [] } if not found; { jobdefs: [name, ...] } if found. Never hallucinate jobdef names.
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
let spec = {
|
|
48
|
+
name: 'find-jobdef',
|
|
49
|
+
description: description,
|
|
50
|
+
inputSchema: z.object({
|
|
51
|
+
name: z.string()
|
|
52
|
+
}),
|
|
53
|
+
handler: async (params) => {
|
|
54
|
+
if (params.name != null) {
|
|
55
|
+
if (params.name.endsWith('.jobdef')) {
|
|
56
|
+
params.name = params.name.slice(0, -7);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
params.tool = 'find';
|
|
60
|
+
let r = await _findJobdef(params);
|
|
61
|
+
return r;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return spec;
|
|
65
|
+
}
|
|
66
|
+
export default findJobdef;
|
|
67
|
+
|