@sassoftware/sas-score-mcp-serverjs 1.1.1 → 1.1.3
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/cli.js +2 -2
- package/package.json +1 -1
- package/src/oauthHandlers/authorize.js +7 -2
- package/src/toolHelpers/_casScore.js +31 -31
- package/src/toolSet/casModelScore.js +93 -93
- package/src/toolSet/casProgramScore.js +105 -105
- package/src/toolSet/devaScore.js +66 -66
- package/src/toolSet/findJob.js +74 -74
- package/src/toolSet/findJobdef.js +67 -67
- package/src/toolSet/findLibrary.js +73 -73
- package/src/toolSet/findMas.js +2 -2
- package/src/toolSet/getEnv.js +57 -57
- package/src/toolSet/jobDescribe.js +65 -65
- package/src/toolSet/jobScore.js +90 -90
- package/src/toolSet/jobdefDescribe.js +67 -67
- package/src/toolSet/jobdefScore.js +85 -85
- package/src/toolSet/listJobdefs.js +70 -70
- package/src/toolSet/listJobs.js +68 -68
- package/src/toolSet/listLibraries.js +84 -84
- package/src/toolSet/masScore.js +95 -95
- package/src/toolSet/programScore.js +96 -96
- package/src/toolSet/readTable.js +80 -80
- package/src/toolSet/sasQuery.js +83 -83
- package/src/toolSet/setContext.js +70 -70
package/cli.js
CHANGED
|
@@ -266,12 +266,12 @@ let authFlow = process.env.AUTHFLOW;
|
|
|
266
266
|
let mcpHost = process.env.MCPHOST;
|
|
267
267
|
|
|
268
268
|
if (authFlow === 'oauth' || authFlow === 'oauthclient') {
|
|
269
|
-
authFlow = 'bearer';
|
|
270
269
|
authExternal = (authFlow === 'oauthclient') ? true : false;
|
|
270
|
+
authFlow = 'bearer';
|
|
271
271
|
} else if (authFlow === 'bearer') {
|
|
272
272
|
authExternal = true; // in bearer token flow we assume the token is generated externally and passed in via env variable or token file, so we set authExternal to true to indicate that
|
|
273
273
|
}
|
|
274
|
-
|
|
274
|
+
let autoLogon = process.env.AUTOLOGON != null ? process.env.AUTOLOGON.toUpperCase() : "FALSE";
|
|
275
275
|
const appEnvBase = {
|
|
276
276
|
version: version,
|
|
277
277
|
mcpType: mcpType,
|
package/package.json
CHANGED
|
@@ -8,12 +8,17 @@ import baseUrl from "./baseUrl.js";
|
|
|
8
8
|
function authorize(req, res, appContext, pkceStore, codeStore) {
|
|
9
9
|
const { response_type, redirect_uri, state, scope } = req.query;
|
|
10
10
|
console.error("===============================================================");
|
|
11
|
+
console.error("[NOTE] query parameters:", { response_type, redirect_uri, state, scope });
|
|
12
|
+
let callbackUri = appContext.mcpHost + '/callback';
|
|
13
|
+
console.error("[Note] Constructed callbackUri:", callbackUri);
|
|
14
|
+
console.error("[Note] appContext.AUTHEXTERNAL:", appContext.AUTHEXTERNAL);
|
|
11
15
|
if (appContext.AUTHEXTERNAL === true) {
|
|
12
16
|
console.error('*************************************************************');
|
|
13
17
|
console.error("[Error] Received request for /authorize endpoint with external authorization expected");
|
|
14
18
|
console.error('*************************************************************');
|
|
19
|
+
callbackUri = redirect_uri;
|
|
15
20
|
}
|
|
16
|
-
|
|
21
|
+
|
|
17
22
|
if (response_type !== "code") {
|
|
18
23
|
return res.status(400).json({ error: "unsupported_response_type" });
|
|
19
24
|
}
|
|
@@ -27,7 +32,7 @@ function authorize(req, res, appContext, pkceStore, codeStore) {
|
|
|
27
32
|
|
|
28
33
|
pkceStore.set(ourState, { codeVerifier, clientRedirectUri: redirect_uri, clientState: state, codeChallenge });
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
|
|
31
36
|
console.error("[Note] callbackUri:", callbackUri);
|
|
32
37
|
let urlConfig = {
|
|
33
38
|
response_type: "code",
|
|
@@ -1,32 +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
|
-
}
|
|
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
32
|
export default _casScore;
|
|
@@ -1,93 +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;
|
|
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;
|
|
@@ -1,105 +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;
|
|
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
|
@@ -1,66 +1,66 @@
|
|
|
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
|
-
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
|
-
` : `
|
|
15
|
-
deva-score — compute a numeric score based on two input values.
|
|
16
|
-
|
|
17
|
-
USE when: calculate deva score, score these values, compute score for numbers
|
|
18
|
-
DO NOT USE for: model scoring (use ${brand}model-score), statistical calculations, data lookup
|
|
19
|
-
|
|
20
|
-
PARAMETERS
|
|
21
|
-
- a: number (required) — first input value
|
|
22
|
-
- b: number (required) — second input value
|
|
23
|
-
|
|
24
|
-
FORMULA: (a + b) * 42
|
|
25
|
-
|
|
26
|
-
ROUTING RULES
|
|
27
|
-
- "calculate deva score for 5 and 10" → { a: 5, b: 10 }
|
|
28
|
-
- "score 1 and 2" → { a: 1, b: 2 }
|
|
29
|
-
- "deva score a=3, b=7" → { a: 3, b: 7 }
|
|
30
|
-
- Multiple numbers → chain calls left-to-right: call(first, second), then call(result, third)
|
|
31
|
-
|
|
32
|
-
EXAMPLES
|
|
33
|
-
- "Calculate deva score for 5 and 10" → { a: 5, b: 10 } returns 630
|
|
34
|
-
- "Score 1 and 2" → { a: 1, b: 2 } returns 126
|
|
35
|
-
- "Deva score 20 and 30" → { a: 20, b: 30 } returns 2100
|
|
36
|
-
|
|
37
|
-
NEGATIVE EXAMPLES (do not route here)
|
|
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)
|
|
41
|
-
|
|
42
|
-
RESPONSE
|
|
43
|
-
Returns { score: (a + b) * 42 }
|
|
44
|
-
`;
|
|
45
|
-
let spec = {
|
|
46
|
-
name: 'deva-score',
|
|
47
|
-
description: description,
|
|
48
|
-
inputSchema: z.object({
|
|
49
|
-
a: z.number(),
|
|
50
|
-
b: z.number(),
|
|
51
|
-
}),
|
|
52
|
-
handler: async ({ a, b }) => {
|
|
53
|
-
console.error(a, b);
|
|
54
|
-
let r = { score: (a + b) * 42 };
|
|
55
|
-
console.error('deva score result', r);
|
|
56
|
-
return {
|
|
57
|
-
content: [{ type: 'text', text: 'deva score result: ' + JSON.stringify(r) }],
|
|
58
|
-
structuredContent: r
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return spec;
|
|
64
|
-
}
|
|
65
|
-
export default devaScore;
|
|
66
|
-
|
|
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
|
+
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
|
+
` : `
|
|
15
|
+
deva-score — compute a numeric score based on two input values.
|
|
16
|
+
|
|
17
|
+
USE when: calculate deva score, score these values, compute score for numbers
|
|
18
|
+
DO NOT USE for: model scoring (use ${brand}model-score), statistical calculations, data lookup
|
|
19
|
+
|
|
20
|
+
PARAMETERS
|
|
21
|
+
- a: number (required) — first input value
|
|
22
|
+
- b: number (required) — second input value
|
|
23
|
+
|
|
24
|
+
FORMULA: (a + b) * 42
|
|
25
|
+
|
|
26
|
+
ROUTING RULES
|
|
27
|
+
- "calculate deva score for 5 and 10" → { a: 5, b: 10 }
|
|
28
|
+
- "score 1 and 2" → { a: 1, b: 2 }
|
|
29
|
+
- "deva score a=3, b=7" → { a: 3, b: 7 }
|
|
30
|
+
- Multiple numbers → chain calls left-to-right: call(first, second), then call(result, third)
|
|
31
|
+
|
|
32
|
+
EXAMPLES
|
|
33
|
+
- "Calculate deva score for 5 and 10" → { a: 5, b: 10 } returns 630
|
|
34
|
+
- "Score 1 and 2" → { a: 1, b: 2 } returns 126
|
|
35
|
+
- "Deva score 20 and 30" → { a: 20, b: 30 } returns 2100
|
|
36
|
+
|
|
37
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
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)
|
|
41
|
+
|
|
42
|
+
RESPONSE
|
|
43
|
+
Returns { score: (a + b) * 42 }
|
|
44
|
+
`;
|
|
45
|
+
let spec = {
|
|
46
|
+
name: 'deva-score',
|
|
47
|
+
description: description,
|
|
48
|
+
inputSchema: z.object({
|
|
49
|
+
a: z.number(),
|
|
50
|
+
b: z.number(),
|
|
51
|
+
}),
|
|
52
|
+
handler: async ({ a, b }) => {
|
|
53
|
+
console.error(a, b);
|
|
54
|
+
let r = { score: (a + b) * 42 };
|
|
55
|
+
console.error('deva score result', r);
|
|
56
|
+
return {
|
|
57
|
+
content: [{ type: 'text', text: 'deva score result: ' + JSON.stringify(r) }],
|
|
58
|
+
structuredContent: r
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return spec;
|
|
64
|
+
}
|
|
65
|
+
export default devaScore;
|
|
66
|
+
|