@sassoftware/sas-score-mcp-serverjs 1.0.1-30 → 1.0.1-32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.skills/agents/sas-score-mcp-serverjs-agent.md +1 -1
- package/.skills/copilot-instructions.md +57 -26
- package/.skills/skills/detail-strategy/SKILL.md +95 -49
- package/.skills/skills/find-resources/SKILL.md +38 -31
- package/.skills/skills/list-resource/SKILL.md +93 -33
- package/.skills/skills/request-routing/SKILL.md +9 -4
- package/.skills/skills/score-strategy/SKILL.md +21 -3
- package/README.md +62 -43
- package/openApi.yaml +121 -121
- package/package.json +7 -5
- package/scripts/docs/oauth-http-transport.md +2 -2
- package/scripts/plot_msrp_usa.py +49 -0
- package/scripts/refreshtoken.js +57 -57
- package/src/createMcpServer.js +0 -1
- package/src/openApi.yaml +121 -121
- package/src/toolHelpers/_findJob.js +12 -0
- package/src/toolHelpers/_findJobdef.js +10 -0
- package/src/toolHelpers/_findLibrary.js +10 -0
- package/src/toolHelpers/_findMas.js +12 -0
- package/src/toolHelpers/_findTable.js +10 -0
- package/src/toolHelpers/_listJobs.js +2 -2
- package/src/toolHelpers/{_listModels.js → _listMas.js} +4 -4
- package/src/toolSet/devaScore.js +61 -61
- package/src/toolSet/findJob.js +2 -1
- package/src/toolSet/findJobdef.js +2 -2
- package/src/toolSet/findLibrary.js +68 -68
- package/src/toolSet/findMas.js +59 -0
- package/src/toolSet/findTable.js +2 -2
- package/src/toolSet/jobInfo.js +59 -0
- package/src/toolSet/jobdefInfo.js +59 -0
- package/src/toolSet/listJobdefs.js +61 -61
- package/src/toolSet/listJobs.js +61 -61
- package/src/toolSet/listLibraries.js +78 -78
- package/src/toolSet/{listModels.js → listMas.js} +61 -56
- package/src/toolSet/listTables.js +66 -66
- package/src/toolSet/makeTools.js +21 -12
- package/src/toolSet/{modelInfo.js → masInfo.js} +12 -12
- package/src/toolSet/{modelScore.js → masScore.js} +3 -3
- package/src/toolSet/readTable.js +63 -63
- package/src/toolSet/runMacro.js +82 -82
- package/src/toolSet/sasQuery.js +77 -77
- package/src/toolSet/setContext.js +65 -65
- package/src/toolSet/superstat.js +61 -61
- package/src/toolSet/tableInfo.js +58 -58
- package/scripts/optimize_final.py +0 -140
- package/scripts/optimize_tools.py +0 -99
- package/scripts/setup-skills.js +0 -34
- package/scripts/token.txt +0 -1
- package/scripts/update_descriptions.py +0 -46
- package/src/toolSet/findModel.js +0 -60
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
|
|
@@ -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.log ("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,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 _listLibrary from './_listLibrary.js';
|
|
7
|
+
async function _findLibrary(params) {
|
|
8
|
+
return await _listLibrary(params);
|
|
9
|
+
}
|
|
10
|
+
export default _findLibrary;
|
|
@@ -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 _listMas from './_listMas.js';
|
|
7
|
+
async function _findMas(params) {
|
|
8
|
+
let r = await _listMas(params);
|
|
9
|
+
console.log ("findMas result:" , r);
|
|
10
|
+
return r;
|
|
11
|
+
}
|
|
12
|
+
export default _findMas;
|
|
@@ -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 _listTables from './_listTables.js';
|
|
7
|
+
async function _findTable(params) {
|
|
8
|
+
return await _listTables(params);
|
|
9
|
+
}
|
|
10
|
+
export default _findTable;
|
|
@@ -42,9 +42,9 @@ async function _listJobs(params) {
|
|
|
42
42
|
names[jname] = {parameters: (value == null) ? {} : value.toJS() };
|
|
43
43
|
}
|
|
44
44
|
});
|
|
45
|
-
|
|
45
|
+
console.error('parameters', JSON.stringify(names, null, 2));
|
|
46
46
|
let response = {jobs: Object.keys(names)};
|
|
47
|
-
console.error('
|
|
47
|
+
console.error('response', JSON.stringify(response, null, 2));
|
|
48
48
|
|
|
49
49
|
if (name != null) {
|
|
50
50
|
response = { name: name, parameters: names[name].parameters };
|
|
@@ -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;
|
package/src/toolSet/devaScore.js
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
*/
|
|
5
|
-
import { z } from 'zod';
|
|
6
|
-
|
|
7
|
-
function devaScore(_appContext) {
|
|
8
|
-
|
|
9
|
-
let description = `
|
|
10
|
-
deva-score — compute a numeric score based on two input values.
|
|
11
|
-
|
|
12
|
-
USE when: calculate deva score, score these values, compute score for numbers
|
|
13
|
-
DO NOT USE for: model scoring (use model-score), statistical calculations, data lookup
|
|
14
|
-
|
|
15
|
-
PARAMETERS
|
|
16
|
-
- a: number (required) — first input value
|
|
17
|
-
- b: number (required) — second input value
|
|
18
|
-
|
|
19
|
-
FORMULA: (a + b) * 42
|
|
20
|
-
|
|
21
|
-
ROUTING RULES
|
|
22
|
-
- "calculate deva score for 5 and 10" → { a: 5, b: 10 }
|
|
23
|
-
- "score 1 and 2" → { a: 1, b: 2 }
|
|
24
|
-
- "deva score a=3, b=7" → { a: 3, b: 7 }
|
|
25
|
-
- Multiple numbers → chain calls left-to-right: call(first, second), then call(result, third)
|
|
26
|
-
|
|
27
|
-
EXAMPLES
|
|
28
|
-
- "Calculate deva score for 5 and 10" → { a: 5, b: 10 } returns 630
|
|
29
|
-
- "Score 1 and 2" → { a: 1, b: 2 } returns 126
|
|
30
|
-
- "Deva score 20 and 30" → { a: 20, b: 30 } returns 2100
|
|
31
|
-
|
|
32
|
-
NEGATIVE EXAMPLES (do not route here)
|
|
33
|
-
- "Score this customer with credit model" (use model-score)
|
|
34
|
-
- "Calculate the mean of these values" (use run-sas-program or sas-query)
|
|
35
|
-
- "Statistical analysis of numbers" (use sas-query)
|
|
36
|
-
|
|
37
|
-
RESPONSE
|
|
38
|
-
Returns { score: (a + b) * 42 }
|
|
39
|
-
`;
|
|
40
|
-
let spec = {
|
|
41
|
-
name: 'deva-score',
|
|
42
|
-
description: description,
|
|
43
|
-
inputSchema: z.object({
|
|
44
|
-
a: z.number(),
|
|
45
|
-
b: z.number(),
|
|
46
|
-
}),
|
|
47
|
-
handler: async ({ a, b }) => {
|
|
48
|
-
console.error(a, b);
|
|
49
|
-
let r = { score: (a + b) * 42 };
|
|
50
|
-
console.error('deva score result', r);
|
|
51
|
-
return {
|
|
52
|
-
content: [{ type: 'text', text: 'deva score result: ' + JSON.stringify(r) }],
|
|
53
|
-
structuredContent: r
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return spec;
|
|
59
|
-
}
|
|
60
|
-
export default devaScore;
|
|
61
|
-
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
|
|
7
|
+
function devaScore(_appContext) {
|
|
8
|
+
|
|
9
|
+
let description = `
|
|
10
|
+
deva-score — compute a numeric score based on two input values.
|
|
11
|
+
|
|
12
|
+
USE when: calculate deva score, score these values, compute score for numbers
|
|
13
|
+
DO NOT USE for: model scoring (use model-score), statistical calculations, data lookup
|
|
14
|
+
|
|
15
|
+
PARAMETERS
|
|
16
|
+
- a: number (required) — first input value
|
|
17
|
+
- b: number (required) — second input value
|
|
18
|
+
|
|
19
|
+
FORMULA: (a + b) * 42
|
|
20
|
+
|
|
21
|
+
ROUTING RULES
|
|
22
|
+
- "calculate deva score for 5 and 10" → { a: 5, b: 10 }
|
|
23
|
+
- "score 1 and 2" → { a: 1, b: 2 }
|
|
24
|
+
- "deva score a=3, b=7" → { a: 3, b: 7 }
|
|
25
|
+
- Multiple numbers → chain calls left-to-right: call(first, second), then call(result, third)
|
|
26
|
+
|
|
27
|
+
EXAMPLES
|
|
28
|
+
- "Calculate deva score for 5 and 10" → { a: 5, b: 10 } returns 630
|
|
29
|
+
- "Score 1 and 2" → { a: 1, b: 2 } returns 126
|
|
30
|
+
- "Deva score 20 and 30" → { a: 20, b: 30 } returns 2100
|
|
31
|
+
|
|
32
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
33
|
+
- "Score this customer with credit model" (use model-score)
|
|
34
|
+
- "Calculate the mean of these values" (use run-sas-program or sas-query)
|
|
35
|
+
- "Statistical analysis of numbers" (use sas-query)
|
|
36
|
+
|
|
37
|
+
RESPONSE
|
|
38
|
+
Returns { score: (a + b) * 42 }
|
|
39
|
+
`;
|
|
40
|
+
let spec = {
|
|
41
|
+
name: 'deva-score',
|
|
42
|
+
description: description,
|
|
43
|
+
inputSchema: z.object({
|
|
44
|
+
a: z.number(),
|
|
45
|
+
b: z.number(),
|
|
46
|
+
}),
|
|
47
|
+
handler: async ({ a, b }) => {
|
|
48
|
+
console.error(a, b);
|
|
49
|
+
let r = { score: (a + b) * 42 };
|
|
50
|
+
console.error('deva score result', r);
|
|
51
|
+
return {
|
|
52
|
+
content: [{ type: 'text', text: 'deva score result: ' + JSON.stringify(r) }],
|
|
53
|
+
structuredContent: r
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return spec;
|
|
59
|
+
}
|
|
60
|
+
export default devaScore;
|
|
61
|
+
|
package/src/toolSet/findJob.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
import _listJobs from '../toolHelpers/_listJobs.js';
|
|
7
|
+
import _findJob from '../toolHelpers/_findJob.js';
|
|
7
8
|
function findJob(_appContext) {
|
|
8
9
|
|
|
9
10
|
let description = `
|
|
@@ -45,7 +46,7 @@ Returns { jobs: [] } if not found; { jobs: [name, ...] } if found. Never halluci
|
|
|
45
46
|
name: z.string()
|
|
46
47
|
}),
|
|
47
48
|
handler: async (params) => {
|
|
48
|
-
let r = await
|
|
49
|
+
let r = await _findJob(params);
|
|
49
50
|
return r;
|
|
50
51
|
}
|
|
51
52
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
import
|
|
6
|
+
import _findJobdef from '../toolHelpers/_findJobdef.js';
|
|
7
7
|
function findJobdef(_appContext) {
|
|
8
8
|
let llmDescription= {
|
|
9
9
|
"purpose": "Map natural language requests to find a jobdef (job definition) in SAS Viya and return structured results.",
|
|
@@ -54,7 +54,7 @@ Returns { jobdefs: [] } if not found; { jobdefs: [name, ...] } if found. Never h
|
|
|
54
54
|
name: z.string()
|
|
55
55
|
}),
|
|
56
56
|
handler: async (params) => {
|
|
57
|
-
let r = await
|
|
57
|
+
let r = await _findJobdef(params);
|
|
58
58
|
return r;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
*/
|
|
5
|
-
import { z } from 'zod';
|
|
6
|
-
import _listLibrary from '../toolHelpers/_listLibrary.js';
|
|
7
|
-
function findLibrary(_appContext) {
|
|
8
|
-
|
|
9
|
-
let description = `
|
|
10
|
-
find-library — locate a specific CAS or SAS library.
|
|
11
|
-
|
|
12
|
-
USE when: find library, find lib, does library exist, is library available, lookup library
|
|
13
|
-
DO NOT USE for: list libraries (use list-libraries), find table/job/jobdef/model (use respective tools), table structure (use table-info), create library (use run-sas-program)
|
|
14
|
-
|
|
15
|
-
PARAMETERS
|
|
16
|
-
- name: string (required) — library/caslib name; if multiple supplied, use first
|
|
17
|
-
- server: 'cas' | 'sas' (default: 'cas') — target environment
|
|
18
|
-
|
|
19
|
-
ROUTING RULES
|
|
20
|
-
- "find lib <name>" → { name: "<name>", server: "cas" }
|
|
21
|
-
- "find lib <name> in cas" → { name: "<name>", server: "cas" }
|
|
22
|
-
- "find library <name> in sas" → { name: "<name>", server: "sas" }
|
|
23
|
-
- "does library <name> exist" → { name: "<name>", server: "cas" }
|
|
24
|
-
- "find lib" with no name → ask "Which library name would you like to find?"
|
|
25
|
-
- "list libraries / list libs" → use list-libraries instead
|
|
26
|
-
- "tables in <lib>" → use list-tables instead
|
|
27
|
-
|
|
28
|
-
EXAMPLES
|
|
29
|
-
- "find lib Public" → { name: "Public", server: "cas" }
|
|
30
|
-
- "find library sasuser in sas" → { name: "sasuser", server: "sas" }
|
|
31
|
-
- "does library Formats exist" → { name: "Formats", server: "cas" }
|
|
32
|
-
|
|
33
|
-
NEGATIVE EXAMPLES (do not route here)
|
|
34
|
-
- "list libs" (use list-libraries)
|
|
35
|
-
- "show tables in Public" (use list-tables)
|
|
36
|
-
- "find table cars in sashelp" (use find-table)
|
|
37
|
-
- "find job cars_job" (use find-job)
|
|
38
|
-
|
|
39
|
-
ERRORS
|
|
40
|
-
Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Never hallucinate library names.
|
|
41
|
-
`;
|
|
42
|
-
|
|
43
|
-
let spec = {
|
|
44
|
-
name: 'find-library',
|
|
45
|
-
description: description,
|
|
46
|
-
inputSchema: z.object({
|
|
47
|
-
name: z.string(),
|
|
48
|
-
server: z.string().optional()
|
|
49
|
-
}),
|
|
50
|
-
|
|
51
|
-
handler: async (params) => {
|
|
52
|
-
// normalize server to lowercase & default
|
|
53
|
-
if (!params.server) params.server = 'cas';
|
|
54
|
-
params.server = params.server.toLowerCase();
|
|
55
|
-
|
|
56
|
-
// If multiple names passed (comma or space separated), take the first token (defensive)
|
|
57
|
-
if (params.name && /[,\s]+/.test(params.name.trim())) {
|
|
58
|
-
params.name = params.name.split(/[,\s]+/).filter(Boolean)[0];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
let r = await _listLibrary(params);
|
|
62
|
-
return r;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return spec;
|
|
66
|
-
}
|
|
67
|
-
export default findLibrary;
|
|
68
|
-
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import _listLibrary from '../toolHelpers/_listLibrary.js';
|
|
7
|
+
function findLibrary(_appContext) {
|
|
8
|
+
|
|
9
|
+
let description = `
|
|
10
|
+
find-library — locate a specific CAS or SAS library.
|
|
11
|
+
|
|
12
|
+
USE when: find library, find lib, does library exist, is library available, lookup library
|
|
13
|
+
DO NOT USE for: list libraries (use list-libraries), find table/job/jobdef/model (use respective tools), table structure (use table-info), create library (use run-sas-program)
|
|
14
|
+
|
|
15
|
+
PARAMETERS
|
|
16
|
+
- name: string (required) — library/caslib name; if multiple supplied, use first
|
|
17
|
+
- server: 'cas' | 'sas' (default: 'cas') — target environment
|
|
18
|
+
|
|
19
|
+
ROUTING RULES
|
|
20
|
+
- "find lib <name>" → { name: "<name>", server: "cas" }
|
|
21
|
+
- "find lib <name> in cas" → { name: "<name>", server: "cas" }
|
|
22
|
+
- "find library <name> in sas" → { name: "<name>", server: "sas" }
|
|
23
|
+
- "does library <name> exist" → { name: "<name>", server: "cas" }
|
|
24
|
+
- "find lib" with no name → ask "Which library name would you like to find?"
|
|
25
|
+
- "list libraries / list libs" → use list-libraries instead
|
|
26
|
+
- "tables in <lib>" → use list-tables instead
|
|
27
|
+
|
|
28
|
+
EXAMPLES
|
|
29
|
+
- "find lib Public" → { name: "Public", server: "cas" }
|
|
30
|
+
- "find library sasuser in sas" → { name: "sasuser", server: "sas" }
|
|
31
|
+
- "does library Formats exist" → { name: "Formats", server: "cas" }
|
|
32
|
+
|
|
33
|
+
NEGATIVE EXAMPLES (do not route here)
|
|
34
|
+
- "list libs" (use list-libraries)
|
|
35
|
+
- "show tables in Public" (use list-tables)
|
|
36
|
+
- "find table cars in sashelp" (use find-table)
|
|
37
|
+
- "find job cars_job" (use find-job)
|
|
38
|
+
|
|
39
|
+
ERRORS
|
|
40
|
+
Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Never hallucinate library names.
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
let spec = {
|
|
44
|
+
name: 'find-library',
|
|
45
|
+
description: description,
|
|
46
|
+
inputSchema: z.object({
|
|
47
|
+
name: z.string(),
|
|
48
|
+
server: z.string().optional()
|
|
49
|
+
}),
|
|
50
|
+
|
|
51
|
+
handler: async (params) => {
|
|
52
|
+
// normalize server to lowercase & default
|
|
53
|
+
if (!params.server) params.server = 'cas';
|
|
54
|
+
params.server = params.server.toLowerCase();
|
|
55
|
+
|
|
56
|
+
// If multiple names passed (comma or space separated), take the first token (defensive)
|
|
57
|
+
if (params.name && /[,\s]+/.test(params.name.trim())) {
|
|
58
|
+
params.name = params.name.split(/[,\s]+/).filter(Boolean)[0];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let r = await _listLibrary(params);
|
|
62
|
+
return r;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return spec;
|
|
66
|
+
}
|
|
67
|
+
export default findLibrary;
|
|
68
|
+
|