@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.
Files changed (121) hide show
  1. package/.skills/.claude-plugin/plugin.json +59 -0
  2. package/.skills/agents/sas-score-mcp-serverjs-agent.md +26 -0
  3. package/.skills/copilot-instructions.md +62 -0
  4. package/.skills/skills/README.md +204 -0
  5. package/.skills/skills/detail-strategy/SKILL.md +316 -0
  6. package/.skills/skills/find-library-server/SKILL.md +62 -0
  7. package/.skills/skills/find-resources/SKILL.md +66 -0
  8. package/.skills/skills/list-library/SKILL.md +30 -0
  9. package/.skills/skills/list-mas-job-jobdef/SKILL.md +31 -0
  10. package/.skills/skills/list-tables/SKILL.md +30 -0
  11. package/.skills/skills/read-strategy/SKILL.md +87 -0
  12. package/.skills/skills/request-routing/SKILL.md +112 -0
  13. package/.skills/skills/score-cas/SKILL.md +95 -0
  14. package/.skills/skills/score-job-jobdef/SKILL.md +58 -0
  15. package/.skills/skills/score-mas-scr/SKILL.md +58 -0
  16. package/.skills/skills/score-program/SKILL.md +59 -0
  17. package/.skills/skills/score-strategy/SKILL.md +39 -0
  18. package/README.md +96 -54
  19. package/cli.js +29 -38
  20. package/openApi.yaml +121 -121
  21. package/package.json +15 -13
  22. package/scripts/docs/SCORE_SKILL_REFERENCE.md +17 -16
  23. package/scripts/docs/TOOL_DESCRIPTION_TEMPLATE.md +3 -3
  24. package/scripts/docs/TOOL_UPDATES_SUMMARY.md +65 -63
  25. package/scripts/docs/oauth-http-transport.md +2 -2
  26. package/scripts/docs/sas-mcp-tools-reference.md +43 -32
  27. package/scripts/plot_msrp_usa.py +49 -0
  28. package/scripts/refreshtoken.js +58 -0
  29. package/scripts/runListScr.mjs +16 -0
  30. package/src/createMcpServer.js +4 -1
  31. package/src/expressMcpServer.js +47 -49
  32. package/src/oauthHandlers/authorize.js +4 -1
  33. package/src/oauthHandlers/baseUrl.js +4 -0
  34. package/src/oauthHandlers/callback.js +4 -0
  35. package/src/oauthHandlers/getMetadata.js +4 -0
  36. package/src/oauthHandlers/index.js +4 -0
  37. package/src/oauthHandlers/token.js +4 -0
  38. package/src/openApi.yaml +121 -121
  39. package/src/processHeaders.js +10 -7
  40. package/src/setupSkills.js +6 -9
  41. package/src/toolHelpers/_casScore.js +32 -0
  42. package/src/toolHelpers/_desc.js +14 -0
  43. package/src/toolHelpers/_findJob.js +12 -0
  44. package/src/toolHelpers/_findJobdef.js +10 -0
  45. package/src/toolHelpers/_findLibrary.js +11 -0
  46. package/src/toolHelpers/_findMas.js +13 -0
  47. package/src/toolHelpers/_findScr.js +36 -0
  48. package/src/toolHelpers/_findTable.js +11 -0
  49. package/src/toolHelpers/_listJobdefs.js +12 -2
  50. package/src/toolHelpers/_listJobs.js +19 -8
  51. package/src/toolHelpers/{_listModels.js → _listMas.js} +4 -4
  52. package/src/toolHelpers/_listScr.js +13 -0
  53. package/src/toolHelpers/{_scrInfo.js → _scrDescribe.js} +4 -4
  54. package/src/toolHelpers/_scrScore.js +2 -2
  55. package/src/toolHelpers/_submitCasl.js +19 -17
  56. package/src/toolHelpers/{_tableInfo.js → _tableDescribe.js} +2 -2
  57. package/src/toolHelpers/getLogonPayload.js +2 -2
  58. package/src/toolSet/casModelScore.js +93 -0
  59. package/src/toolSet/casProgramScore.js +105 -0
  60. package/src/toolSet/devaScore.js +11 -6
  61. package/src/toolSet/findJob.js +74 -59
  62. package/src/toolSet/findJobdef.js +67 -64
  63. package/src/toolSet/findLibrary.js +28 -23
  64. package/src/toolSet/findMas.js +72 -0
  65. package/src/toolSet/findScr.js +69 -0
  66. package/src/toolSet/findTable.js +34 -27
  67. package/src/toolSet/getEnv.js +57 -57
  68. package/src/toolSet/jobDescribe.js +65 -0
  69. package/src/toolSet/jobScore.js +90 -0
  70. package/src/toolSet/jobdefDescribe.js +67 -0
  71. package/src/toolSet/jobdefScore.js +85 -0
  72. package/src/toolSet/listJobdefs.js +17 -8
  73. package/src/toolSet/listJobs.js +15 -8
  74. package/src/toolSet/listLibraries.js +16 -10
  75. package/src/toolSet/listMas.js +71 -0
  76. package/src/toolSet/listScr.js +62 -0
  77. package/src/toolSet/listTables.js +78 -66
  78. package/src/toolSet/{runMacro.js → macroScore.js} +86 -82
  79. package/src/toolSet/makeTools.js +39 -25
  80. package/src/toolSet/masDescribe.js +67 -0
  81. package/src/toolSet/masScore.js +95 -0
  82. package/src/toolSet/{runProgram.js → programScore.js} +96 -93
  83. package/src/toolSet/readTable.js +43 -26
  84. package/src/toolSet/sasQuery.js +24 -18
  85. package/src/toolSet/scrDescribe.js +55 -0
  86. package/src/toolSet/scrScore.js +63 -70
  87. package/src/toolSet/searchAssets.js +1 -1
  88. package/src/toolSet/setContext.js +8 -3
  89. package/src/toolSet/superstat.js +61 -61
  90. package/src/toolSet/tableDescribe.js +65 -0
  91. package/.skills/sas-find-library-smart/SKILL.md +0 -155
  92. package/.skills/sas-find-resource-strategy/SKILL.md +0 -105
  93. package/.skills/sas-list-resource-strategy/SKILL.md +0 -124
  94. package/.skills/sas-list-tables-smart/SKILL.md +0 -128
  95. package/.skills/sas-read-and-score-strategy/SKILL.md +0 -113
  96. package/.skills/sas-read-strategy/SKILL.md +0 -154
  97. package/.skills/sas-request-classifier/SKILL.md +0 -74
  98. package/.skills/sas-score-workflow-strategy/SKILL.md +0 -314
  99. package/.skills_claude/CLAUDE.md +0 -201
  100. package/.skills_claude/agents/sas-score-mcp-serverjs-agent.md +0 -58
  101. package/.skills_claude/enforce-find-resource-strategy.md +0 -35
  102. package/.skills_github/agents/sas-score-mcp-serverjs-agent.md +0 -58
  103. package/.skills_github/copilot-instructions.md +0 -201
  104. package/.skills_github/enforce-find-resource-strategy.md +0 -35
  105. package/scripts/optimize_final.py +0 -140
  106. package/scripts/optimize_tools.py +0 -99
  107. package/scripts/setup-skills.js +0 -34
  108. package/scripts/update_descriptions.py +0 -46
  109. package/src/authpkce.js +0 -219
  110. package/src/handleGetDelete.js +0 -34
  111. package/src/handleRequest.js +0 -112
  112. package/src/hapiMcpServer.js +0 -241
  113. package/src/toolSet/findModel.js +0 -60
  114. package/src/toolSet/listModels.js +0 -56
  115. package/src/toolSet/modelInfo.js +0 -55
  116. package/src/toolSet/modelScore.js +0 -89
  117. package/src/toolSet/runCasProgram.js +0 -98
  118. package/src/toolSet/runJob.js +0 -81
  119. package/src/toolSet/runJobdef.js +0 -82
  120. package/src/toolSet/scrInfo.js +0 -52
  121. package/src/toolSet/tableInfo.js +0 -58
@@ -1,40 +1,44 @@
1
- /*
2
- * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
1
+ /*
2
+ * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { z } from 'zod';
6
6
  import _listLibrary from '../toolHelpers/_listLibrary.js';
7
7
  function findLibrary(_appContext) {
8
-
9
- let description = `
10
- find-library — locate a specific CAS or SAS library.
8
+ const isAgent = _appContext && _appContext.agent;
9
+ let description = isAgent ? `
10
+ find-library — verify a library exists.
11
+ PARAMS: name (string, required), server ('cas'|'sas', required)
12
+ RETURNS: library metadata if found, error if not found
13
+ ` : `
14
+ find-library — locate a specific CAS or SAS library.
11
15
 
12
16
  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)
17
+ DO NOT USE for: list libraries (use ${_appContext.brand}-list-libraries), find table/job/jobdef/model (use respective tools), table structure (use ${_appContext.brand}-table-describe), create library (use ${_appContext.brand}-program-score)
14
18
 
15
19
  PARAMETERS
16
- - name: string (required) library/caslib name; if multiple supplied, use first
17
- - server: 'cas' | 'sas' (default: 'cas') target environment
20
+ - name: string (required) — library/caslib name; if multiple supplied, use first
21
+ - server: 'cas' | 'sas' (required) — target environment
18
22
 
19
23
  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
24
+ - "find lib <name>" → { name: "<name>", server: "cas" }
25
+ - "find lib <name> in cas" → { name: "<name>", server: "cas" }
26
+ - "find library <name> in sas" → { name: "<name>", server: "sas" }
27
+ - "does library <name> exist" → { name: "<name>", server: "cas" }
28
+ - "find lib" with no name → ask "Which library name would you like to find?"
29
+ - "list libraries / list libs" → use ${_appContext.brand}-list-libraries instead
30
+ - "tables in <lib>" → use ${_appContext.brand}-list-tables instead
27
31
 
28
32
  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" }
33
+ - "find lib Public" → { name: "Public", server: "cas" }
34
+ - "find library sasuser in sas" → { name: "sasuser", server: "sas" }
35
+ - "does library Formats exist" → { name: "Formats", server: "cas" }
32
36
 
33
37
  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
+ - "list libs" (use ${_appContext.brand}-list-libraries)
39
+ - "show tables in Public" (use ${_appContext.brand}-list-tables)
40
+ - "find table cars in sashelp" (use ${_appContext.brand}-find-table)
41
+ - "find job cars_job" (use ${_appContext.brand}-find-job)
38
42
 
39
43
  ERRORS
40
44
  Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Never hallucinate library names.
@@ -57,7 +61,7 @@ Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Nev
57
61
  if (params.name && /[,\s]+/.test(params.name.trim())) {
58
62
  params.name = params.name.split(/[,\s]+/).filter(Boolean)[0];
59
63
  }
60
-
64
+ params.tool = 'find';
61
65
  let r = await _listLibrary(params);
62
66
  return r;
63
67
  }
@@ -66,3 +70,4 @@ Returns { libraries: [] } if not found; { libraries: [name, ...] } if found. Nev
66
70
  }
67
71
  export default findLibrary;
68
72
 
73
+
@@ -0,0 +1,72 @@
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 _findmas from '../toolHelpers/_findmas.js';
8
+
9
+
10
+ function findMas(_appContext) {
11
+ const isAgent = _appContext && _appContext.agent;
12
+ let description = isAgent ? `
13
+ find-mas — verify a MAS model exists.
14
+ PARAMS: name (string, required)
15
+ RETURNS: model metadata if found, error if not found
16
+ ` : `
17
+ find-mas — locate a specific MAS mas deployed to MAS server
18
+
19
+ USE when: find mas, does mas exist, is mas deployed, lookup mas, verify mas exists
20
+ DO NOT USE for: list mass (use ${_appContext.brand}-list-mass), mas info/variables (use ${_appContext.brand}-mas-describe), score mas (use ${_appContext.brand}-mas-score), find table/job/lib (use respective tools), scr mass (use ${_appContext.brand}-scr-describe/${_appContext.brand}-scr-score)
21
+
22
+ PARAMETERS
23
+ - name: string (required) — mas name to locate; if multiple supplied, use first
24
+
25
+ ROUTING RULES
26
+ - "find mas <name>" → { name: "<name>" }
27
+ - "find name.mas" → { name: "<name>" }
28
+ - "does mas <name> exist" → { name: "<name>" }
29
+ - "is mas <name> deployed" → { name: "<name>" }
30
+ - "lookup/verify mas <name>" → { name: "<name>" }
31
+ - "find mas" with no name → ask "Which mas name would you like to find?"
32
+ - "find all mass / list mass" → use ${_appContext.brand}-list-mas instead
33
+ - "describe mas / mas info" → use ${_appContext.brand}-mas-describe instead
34
+
35
+ EXAMPLES
36
+ - "find mas mymas" → { name: "mymas" }
37
+ - "does mas churn_score exist" → { name: "churn_score" }
38
+ - "is mas riskmas deployed" → { name: "riskmas" }
39
+ - "lookup mas claims_fraud_v1" → { name: "claims_fraud_v1" }
40
+
41
+ NEGATIVE EXAMPLES (do not route here)
42
+ - "list mass" (use ${_appContext.brand}-list-mas)
43
+ - "score mas mymas" (use ${_appContext.brand}-mas-score)
44
+ - "mas info for churnRisk" (use ${_appContext.brand}-mas-describe)
45
+
46
+ ERRORS
47
+ Returns { mass: [] } if not found; { mass: [name, ...] } if found. Never hallucinate mas names.
48
+ `;
49
+
50
+ let spec = {
51
+ name: 'find-mas',
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('.mas')) {
59
+ params.name = params.name.slice(0, -4);
60
+ }
61
+ }
62
+ params.tool = 'find';
63
+ let r = await _findmas(params);
64
+ return r;
65
+ }
66
+ }
67
+ return spec;
68
+ }
69
+
70
+ export default findMas;
71
+
72
+
@@ -0,0 +1,69 @@
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 _findScr from '../toolHelpers/_findScr.js';
8
+
9
+
10
+ function findScr(_appContext) {
11
+ const isAgent = _appContext && _appContext.agent;
12
+ let description = isAgent ? `
13
+ find-scr — verify an SCR model exists.
14
+ PARAMS: name (string, required)
15
+ RETURNS: SCR model metadata if found, error if not found
16
+ ` : `
17
+ find-scr — locate a specific SCR scr deployed to SCR server
18
+
19
+ USE when: find scr, does scr exist, is scr deployed, lookup scr, verify scr exists
20
+ DO NOT USE for: list scrs (use list-scr), scr info/variables (use scr-describe), score scr (use scr-score), find table/job/lib (use respective tools), mas scr (use mas-describe/mas-score)
21
+
22
+
23
+ PARAMETERS
24
+ - name: string (required) — scr name to locate; if multiple supplied, use first
25
+
26
+ ROUTING RULES
27
+ - "find scr <name>" → { name: "<name>" }
28
+ - "does scr <name> exist" → { name: "<name>" }
29
+ - "is scr <name> deployed" → { name: "<name>" }
30
+ - "lookup/verify scr <name>" → { name: "<name>" }
31
+ - "find scr" with no name → ask "Which scr name would you like to find?"
32
+ - "describe scr / scr info" → use scr-describe instead
33
+
34
+ EXAMPLES
35
+ - "find scr myscr" → { name: "myscr" }
36
+ - "does scr churn_score exist" → { name: "churn_score" }
37
+ - "is scr riskscr deployed" → { name: "riskscr" }
38
+ - "lookup scr claims_fraud_v1" → { name: "claims_fraud_v1" }
39
+
40
+ NEGATIVE EXAMPLES (do not route here)
41
+ - "list scr" (use ${_appContext.brand}-list-scr)
42
+ - "score scr myscr" (use ${_appContext.brand}-scr-score)
43
+ - "scr info for churnRisk" (use ${_appContext.brand}-scr-describe)
44
+
45
+ ERRORS
46
+ Returns { scr: [] } if not found; { scr: [name, ...] } if found. Never hallucinate scr urls.
47
+ `;
48
+
49
+ let spec = {
50
+ name: 'find-scr',
51
+ description: description,
52
+ inputSchema: z.object({
53
+ name: z.string()
54
+ }),
55
+ handler: async (params) => {
56
+ if (params.name.endsWith('.scr')) {
57
+ params.name = params.name.slice(0, -4);
58
+ }
59
+ params.tool = 'find';
60
+ let r = await _findScr(params);
61
+ return r;
62
+ }
63
+ }
64
+ return spec;
65
+ }
66
+
67
+ export default findScr;
68
+
69
+
@@ -1,43 +1,48 @@
1
- /*
2
- * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
1
+ /*
2
+ * Copyright © 2025, SAS Institute Inc., Cary, NC, USA. All Rights Reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
 
6
6
  import { z } from 'zod';
7
7
  //import debug from 'debug';
8
- import _listTables from '../toolHelpers/_listTables.js';
8
+ import _findTable from '../toolHelpers/_findTable.js';
9
9
 
10
10
  function findTable(_appContext) {
11
- let description = `
12
- find-table locate a specific table in a CAS or SAS library.
11
+ const isAgent = _appContext && _appContext.agent;
12
+ let description = isAgent ? `
13
+ find-table — verify a table exists in a library.
14
+ PARAMS: lib (string, required), name (string, required), server ('cas'|'sas', required)
15
+ RETURNS: table metadata if found, error if not found
16
+ ` : `
17
+ find-table — locate a specific table in a CAS or SAS library.
13
18
 
14
19
  USE when: find table, does table exist, is table in library, verify table exists, locate table
15
- DO NOT USE for: list tables (use list-tables), table schema/columns (use table-info), read table data (use read-table), find lib/job/model (use respective tools)
20
+ DO NOT USE for: list tables (use ${_appContext.brand}-list-tables), table schema/columns (use ${_appContext.brand}-table-describe), read table data (use ${_appContext.brand}-read-table), find lib/job/model (use respective tools)
16
21
 
17
22
  PARAMETERS
18
- - lib: string (required) library name (e.g., 'Public', 'sashelp')
19
- - name: string (required) table name to locate
20
- - server: 'cas' | 'sas' . If not specified set it to 'cas' — target environment
23
+ - lib: string (required) — library name (e.g., 'Public', 'sashelp')
24
+ - name: string (required) — table name to locate
25
+ - server: 'cas' | 'sas' (required) — target environment
21
26
 
22
27
  ROUTING RULES
23
- - "find table <name> in <lib>" { lib: "<lib>", name: "<name>", server: "cas" }
24
- - "find table <name> in <lib> in sas" { lib: "<lib>", name: "<name>", server: "sas" }
25
- - "does table <name> exist in <lib>" { lib: "<lib>", name: "<name>", server: "cas" }
26
- - "find table" with missing lib ask "Which library contains the table?"
27
- - "find table" with missing name ask "Which table name would you like to find?"
28
- - "list tables in <lib>" use list-tables instead
28
+ - "find table <name> in <lib>" → { lib: "<lib>", name: "<name>", server: "cas" }
29
+ - "find table <name> in <lib> in sas" → { lib: "<lib>", name: "<name>", server: "sas" }
30
+ - "does table <name> exist in <lib>" → { lib: "<lib>", name: "<name>", server: "cas" }
31
+ - "find table" with missing lib → ask "Which library contains the table?"
32
+ - "find table" with missing name → ask "Which table name would you like to find?"
33
+ - "list tables in <lib>" → use ${_appContext.brand}-list-tables instead
29
34
 
30
35
  EXAMPLES
31
- - "find table iris in Public" { lib: "Public", name: "iris", server: "cas" }
32
- - "find table cars in sashelp in sas" { lib: "sashelp", name: "cars", server: "sas" }
33
- - "does customers exist in mylib" { lib: "mylib", name: "customers", server: "cas" }
34
- - "verify table orders in Samples" { lib: "Samples", name: "orders", server: "cas" }
36
+ - "find table iris in Public" → { lib: "Public", name: "iris", server: "cas" }
37
+ - "find table cars in sashelp in sas" → { lib: "sashelp", name: "cars", server: "sas" }
38
+ - "does customers exist in mylib" → { lib: "mylib", name: "customers", server: "cas" }
39
+ - "verify table orders in Samples" → { lib: "Samples", name: "orders", server: "cas" }
35
40
 
36
41
  NEGATIVE EXAMPLES (do not route here)
37
- - "list tables in Public" (use list-tables)
38
- - "find library Public" (use find-library)
39
- - "what columns in cars?" (use table-info)
40
- - "read data from customers" (use read-table)
42
+ - "list tables in Public" (use ${_appContext.brand}-list-tables)
43
+ - "find library Public" (use ${_appContext.brand}-find-library)
44
+ - "what columns in cars?" (use ${_appContext.brand}-table-describe)
45
+ - "read data from customers" (use ${_appContext.brand}-read-table)
41
46
 
42
47
  ERRORS
43
48
  Returns { tables: [] } if not found; { tables: [name, ...] } if found. Never hallucinate table names.
@@ -47,14 +52,15 @@ Returns { tables: [] } if not found; { tables: [name, ...] } if found. Never hal
47
52
  name: 'find-table',
48
53
  description: description,
49
54
  inputSchema: z.object({
50
- lib: z.string(),
51
- name: z.string(),
52
- server: z.string()
55
+ lib: z.string().min(1),
56
+ name: z.string().min(1),
57
+ server: z.enum(['cas', 'sas'])
53
58
  }),
54
59
 
55
60
  handler: async (params) => {
56
61
  // Check if the params.scenario is a string and parse it
57
- let r = await _listTables(params);
62
+ params.tool = 'find';
63
+ let r = await _findTable(params);
58
64
  return r;
59
65
  }
60
66
  }
@@ -63,3 +69,4 @@ Returns { tables: [] } if not found; { tables: [name, ...] } if found. Never hal
63
69
 
64
70
  export default findTable;
65
71
 
72
+
@@ -1,57 +1,57 @@
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 _getEnv from '../toolHelpers/_getEnv.js';
8
- function getEnv(_appContext) {
9
- let description = `
10
- get-env — retrieve a variable value from the runtime environment.
11
-
12
- USE when: what is the value of, get me, show current, what's the, retrieve environment variable
13
- DO NOT USE for: read table data (use read-table), model info (use model-info), find/run job (use find-job/run-job), set context (use set-context)
14
-
15
- PARAMETERS
16
- - name: string (required) — variable name to retrieve (case-sensitive)
17
-
18
- ROUTING RULES
19
- - "what is the value of <var>" → { name: "<var>" }
20
- - "get me <var>" → { name: "<var>" }
21
- - "show <var>" → { name: "<var>" }
22
- - "get" with no variable → ask "Which variable would you like to retrieve?"
23
- - "what context am I using" → use set-context instead (no params)
24
- - "set <var> to <value>" → use set-context or run-sas-program instead
25
-
26
- EXAMPLES
27
- - "What's the value of myVar" → { name: "myVar" }
28
- - "Get me the configuration variable" → { name: "configuration" }
29
- - "Show the current server setting" → { name: "server" }
30
-
31
- NEGATIVE EXAMPLES (do not route here)
32
- - "Read rows from customers" (use read-table)
33
- - "Get model details for myModel" (use model-info)
34
- - "Set the CAS server to finance-prod" (use set-context)
35
-
36
- ERRORS
37
- Returns variable name with current value, or null if not found. Return structured error with message field.
38
- `;
39
-
40
- let spec = {
41
- name: 'get-env',
42
- description: description,
43
- inputSchema: {
44
- type: 'object',
45
- properties: {
46
- name: { type: 'string' }
47
- },
48
- required: ['name']
49
- },
50
- handler: async (params) => {
51
- return await _getEnv(params);
52
- }
53
- }
54
- return spec;
55
- }
56
- export default getEnv;
57
-
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 _getEnv from '../toolHelpers/_getEnv.js';
8
+ function getEnv(_appContext) {
9
+ let description = `
10
+ get-env — retrieve a variable value from the runtime environment.
11
+
12
+ USE when: what is the value of, get me, show current, what's the, retrieve environment variable
13
+ DO NOT USE for: read table data (use ${_appContext.brand}-read-table), model info (use ${_appContext.brand}-model-info), find/score job (use ${_appContext.brand}-find-job/${_appContext.brand}-job-score), set context (use ${_appContext.brand}-set-context)
14
+
15
+ PARAMETERS
16
+ - name: string (required) — variable name to retrieve (case-sensitive)
17
+
18
+ ROUTING RULES
19
+ - "what is the value of <var>" → { name: "<var>" }
20
+ - "get me <var>" → { name: "<var>" }
21
+ - "show <var>" → { name: "<var>" }
22
+ - "get" with no variable → ask "Which variable would you like to retrieve?"
23
+ - "what context am I using" → use ${_appContext.brand}-set-context instead (no params)
24
+ - "set <var> to <value>" → use ${_appContext.brand}-set-context or ${_appContext.brand}-program-score instead
25
+
26
+ EXAMPLES
27
+ - "What's the value of myVar" → { name: "myVar" }
28
+ - "Get me the configuration variable" → { name: "configuration" }
29
+ - "Show the current server setting" → { name: "server" }
30
+
31
+ NEGATIVE EXAMPLES (do not route here)
32
+ -- "Read rows from customers" (use ${_appContext.brand}-read-table)
33
+ -- "Get model details for myModel" (use ${_appContext.brand}-model-info)
34
+ -- "Set the CAS server to finance-prod" (use ${_appContext.brand}-set-context)
35
+
36
+ ERRORS
37
+ Returns variable name with current value, or null if not found. Return structured error with message field.
38
+ `;
39
+
40
+ let spec = {
41
+ name: 'get-env',
42
+ description: description,
43
+ inputSchema: {
44
+ type: 'object',
45
+ properties: {
46
+ name: { type: 'string' }
47
+ },
48
+ required: ['name']
49
+ },
50
+ handler: async (params) => {
51
+ return await _getEnv(params);
52
+ }
53
+ }
54
+ return spec;
55
+ }
56
+ export default getEnv;
57
+
@@ -0,0 +1,65 @@
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 _findJob from '../toolHelpers/_findJob.js';
7
+ function jobDescribe(_appContext) {
8
+ const isAgent = _appContext && _appContext.agent;
9
+ let description = isAgent ? `
10
+ job-describe — return input schema for a Job model.
11
+ PARAMS: intent ('describe', required), name (string, required)
12
+ RETURNS: job input variable definitions
13
+ ` : `
14
+ job-describe — return information about a specific SAS Viya job.
15
+
16
+ USE when: describe job, show job details, what does job X do, job metadata, inputs/outputs for job
17
+ DO NOT USE for: find job or verify it exists (use ${_appContext.brand}-find-job), list jobs (use ${_appContext.brand}-list-jobs), score job (use ${_appContext.brand}-job-score)
18
+
19
+ PARAMETERS
20
+ - intent: must be 'describe' — only pass if user explicitly asked to describe/inspect a job. Do NOT use for find or verify existence.
21
+ - name: string (required) — name of job whose details are being requested. Should be exact match to job name.
22
+
23
+ ROUTING RULES
24
+ - "describe job <name>" → { name: "<name>" }
25
+ - "describe model <name.job>"
26
+ - "info for job <name>" → { name: "<name>" }
27
+
28
+ EXAMPLES
29
+ - "describe job cars_job_v4" → { name: "cars_job_v4" }
30
+ - "describe metricsRefresh.job" → { name: "metricsRefresh" }
31
+
32
+ NEGATIVE EXAMPLES (do not route here)
33
+ - "list jobs" (use ${_appContext.brand}-list-jobs)
34
+ - "score job cars_job_v4" (use ${_appContext.brand}-job-score)
35
+ - "score jobdef cars_job_v4" (use ${_appContext.brand}-jobdef-score)
36
+
37
+ ERRORS
38
+ Returns job metadata
39
+ `;
40
+
41
+ let spec = {
42
+ name: 'job-describe',
43
+ description: description,
44
+ inputSchema: z.object({
45
+ intent: z.literal('describe'),
46
+ name: z.string()
47
+ }),
48
+ handler: async (params) => {
49
+ const { intent, ...rest } = params;
50
+ if (rest.name != null && rest.name.endsWith('.job')) {
51
+ rest.name = rest.name.slice(0, -4);
52
+ }
53
+ rest.tool = 'describe';
54
+ let r = await _findJob(rest);
55
+ return r;
56
+ }
57
+ }
58
+
59
+
60
+ /* correct spec for registerTool with inputSchema */
61
+
62
+ return spec;
63
+ }
64
+ export default jobDescribe;
65
+
@@ -0,0 +1,90 @@
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 _jobSubmit from '../toolHelpers/_jobSubmit.js';
8
+
9
+ function jobScore(_appContext) {
10
+ const isAgent = _appContext && _appContext.agent;
11
+
12
+ let description = isAgent ? `
13
+ job-score — score by executing a SAS Viya Job model.
14
+ PARAMS: name (string, required), scenario (object, optional)
15
+ RETURNS: job log, ODS output, and any result tables
16
+ ` : `
17
+ job-score — score with a deployed SAS Viya job model.
18
+
19
+ USE when: score with job, run job, execute job model
20
+ DO NOT USE for: arbitrary SAS code (use program-score), macros (use macro-score), list/find jobs
21
+
22
+ PARAMETERS
23
+ - name: string — job name (required)
24
+ - scenario: object — input parameters as JSON (optional, defaults to {}). Example: {month:10, year:2025}
25
+
26
+ ROUTING RULES
27
+ - "score with job xyz" → { name: "xyz" }
28
+ - "score with job xyz with param1=10, param2=val2" → { name: "xyz", scenario: {param1:10, param2:"val2"} }
29
+ - "run job xyz" → { name: "xyz" }
30
+ - "run job xyz with param1=10, param2=val2" → { name: "xyz", scenario: {param1:10, param2:"val2"} }
31
+
32
+ EXAMPLES
33
+ - "score with job xyz" → { name: "xyz" }
34
+ - "score with job monthly_etl with month=10, year=2025" → { name: "monthly_etl", scenario: {month:10, year:2025} }
35
+ - "score with monthly_etl.job with month=10, year=2025" → { name: "monthly_etl", scenario: {month:10, year:2025} }
36
+ - "run job xyz" → { name: "xyz" }
37
+ - "run job monthly_etl with month=10, year=2025" → { name: "monthly_etl", scenario: {month:10, year:2025} }
38
+
39
+ NEGATIVE EXAMPLES (do not route here)
40
+ - "run SAS code" (use program-score)
41
+ - "score macro X" (use macro-score)
42
+ - "list jobs" (use list-jobs)
43
+ - "find job X" (use find-job)
44
+
45
+ ERRORS
46
+ Returns log output, listings, tables from job. Error if job not found.
47
+ `;
48
+
49
+ let spec = {
50
+ name: 'job-score',
51
+ description: description,
52
+ inputSchema: z.object({
53
+ name: z.string(),
54
+ scenario: z.any()
55
+ }),
56
+ handler: async (params) => {
57
+ let {scenario, name} = params;
58
+
59
+ if(name.endsWith('.job')) {
60
+ params.name = name.slice(0, -4);
61
+ }
62
+ // Convert the scenario string to an object
63
+ // Example: "x=1, y=2, z=3" to { x: 1, y: 2, z: 3 }
64
+ let scenarioObj = {};
65
+ let count = 0;
66
+ if (typeof scenario === 'object') {
67
+ scenarioObj = scenario;
68
+ } else if (Array.isArray(scenario)) {
69
+ scenarioObj = scenario[0];
70
+ } else {
71
+ //console.error('Incoming scenario', scenario);
72
+ scenarioObj = scenario.split(',').reduce((acc, pair) => {
73
+ let [key, value] = pair.split('=');
74
+ acc[key.trim()] = value;
75
+ count++;
76
+ return acc;
77
+ }, {});
78
+ }
79
+ params.scenario = scenarioObj;
80
+ params.type = 'job';
81
+ // Provide runtime context for auth and server settings
82
+ let r = await _jobSubmit(params);
83
+ return r;
84
+ }
85
+ };
86
+ return spec;
87
+ }
88
+
89
+ export default jobScore;
90
+
@@ -0,0 +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 _findJobdef from '../toolHelpers/_findJobdef.js';
7
+ function jobdefDescribe(_appContext) {
8
+ const isAgent = _appContext && _appContext.agent;
9
+ let description = isAgent ? `
10
+ jobdef-describe — return input schema for a JobDef model.
11
+ PARAMS: intent ('describe', required), name (string, required)
12
+ RETURNS: jobdef input variable definitions
13
+ ` : `
14
+ jobdef-describe — return information about a specific SAS Viya jobdef.
15
+
16
+ USE when: describe jobdef, show jobdef details, what does jobdef X do, jobdef metadata, inputs/outputs for jobdef
17
+ DO NOT USE for: find jobdef or verify it exists (use ${_appContext.brand}-find-jobdef), list jobdefs (use ${_appContext.brand}-list-jobdefs), score jobdef (use ${_appContext.brand}-jobdef-score)
18
+
19
+ PARAMETERS
20
+ - intent: must be 'describe' — only pass if user explicitly asked to describe/inspect a jobdef. Do NOT use for find or verify existence.
21
+ - name: string (required) — name of jobdef whose details are being requested. Should be exact match to jobdef name.
22
+
23
+ ROUTING RULES
24
+ - "describe jobdef <name>" → { name: "<name>" }
25
+ - "describe <name.jobdef>"
26
+ - "describe model <name.jobdef>"
27
+ - "info for jobdef <name>" → { name: "<name>" }
28
+
29
+ EXAMPLES
30
+ - "describe jobdef cars_job_v4" → { name: "cars_job_v4" }
31
+ - "describe metricsRefresh.jobdef" → { name: "metricsRefresh" }
32
+ - "info for jobdef ETL" → { name: "ETL" }
33
+
34
+ NEGATIVE EXAMPLES (do not route here)
35
+ - "list jobdefs" (use ${_appContext.brand}-list-jobdefs)
36
+ - "score jobdef cars_job_v4" (use ${_appContext.brand}-jobdef-score)
37
+ - "execute jobdef cars_job_v4" (use ${_appContext.brand}-jobdef-score)
38
+
39
+ ERRORS
40
+ Returns job metadata
41
+ `;
42
+
43
+ let spec = {
44
+ name: 'jobdef-describe',
45
+ description: description,
46
+ inputSchema: z.object({
47
+ intent: z.literal('describe'),
48
+ name: z.string()
49
+ }),
50
+ handler: async (params) => {
51
+ const { intent, ...rest } = params;
52
+ if (rest.name != null && rest.name.endsWith('.jobdef')) {
53
+ rest.name = rest.name.slice(0, -7);
54
+ }
55
+ rest.tool = 'describe';
56
+ let r = await _findJobdef(rest);
57
+ return r;
58
+ }
59
+ }
60
+
61
+
62
+ /* correct spec for registerTool with inputSchema */
63
+
64
+ return spec;
65
+ }
66
+ export default jobdefDescribe;
67
+