Skip to content

Commit 9635389

Browse files
authored
SAS compute tools (#14)
* Correct typo * Add basic compute server related tools * Add comments to Compute Server related tools * Use return_items * feat!: reusable compute sessions, reset tool, and compute discovery tools Add Tier 6 compute tools (list_compute_contexts, list_compute_libraries, list_compute_tables, list_compute_columns) and a reset_compute_session tool. Compute sessions are now pooled per authenticated user and compute context so repeat calls skip the slow session spin-up; cached sessions are validated before reuse, transparently recreated if Viya reaps them, and deleted on server shutdown via a FastMCP lifespan. BREAKING CHANGE: execute_sas_code now runs in a reusable session, so SAS state (WORK tables, macro variables, assigned librefs) persists across successive calls instead of being discarded per call. Use reset_compute_session to start from a clean session. Also harden get_context_id/create_session with raise_for_status, encode the context-name query parameter, add unit and live integration coverage for the new tools (including an end-to-end reuse/reset/recreate test), update the README and CHANGELOG, and bump the version to 1.2.0. Assisted by Claude Code. --------- Signed-off-by: sbxxab <xavier.bizoux@sas.com> Signed-off-by: David Weik <david.weik@sas.com>
1 parent 512531b commit 9635389

18 files changed

Lines changed: 1836 additions & 384 deletions

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
# Changelog
22

3+
## [1.2.0] - 2026-06-15
4+
5+
### Added
6+
- **Compute service discovery tools**`list_compute_contexts`, `list_compute_libraries`, `list_compute_tables`, `list_compute_columns` — browse compute contexts and the SAS libraries/tables/columns visible inside a compute session. Brings the tool count to 32.
7+
- **`reset_compute_session` tool** — deletes the cached compute session for the caller and compute context, discarding its SAS state (WORK tables, macro variables, assigned librefs) so the next call starts from a fresh session. Defaults to the configured execution context.
8+
- **Reusable, per-user compute session cache** (`_ComputeSessionCache` in `viya_utils.py`) — one warm compute session is kept per authenticated user and compute context, so repeat calls skip the slow session spin-up. Keyed by the JWT `sub` claim (falling back to other identity claims, then a token hash) so multi-user HTTP deployments never share a session. Cached sessions are validated before reuse and transparently recreated if Viya has reaped them for inactivity.
9+
- **Compute session shutdown cleanup** — both server entry points register a FastMCP `lifespan` that deletes all cached compute sessions on shutdown (best effort), so warm sessions don't linger until Viya's idle reaper collects them.
10+
- **Integration coverage for every new tool**`test_compute_discovery_workflow` and `test_compute_session_reuse_and_reset` (which proves reuse, deletion, and recreation end to end against a live Viya), wired into the `test_every_tool_has_integration_coverage` guard.
11+
- **`return_items` helper** (`viya_client.py`) — shared field-projection used by the compute discovery tools.
12+
13+
### Changed — BREAKING
14+
- **`execute_sas_code` is now stateful across calls.** It runs in the reusable per-user compute session, so SAS WORK tables, macro variables, and assigned librefs persist between successive calls instead of being discarded with a per-call session. Call `reset_compute_session` to start from a clean session. (Previously every call created and tore down its own session.)
15+
16+
### Changed
17+
- `get_context_id` and `create_session` now call `raise_for_status()`, so an auth/permission failure surfaces as a real `HTTPStatusError` instead of a misleading "compute context not found" or a `KeyError`.
18+
- `get_context_id` builds its query with httpx `params=` instead of string interpolation, so compute context names containing reserved characters (`&`, `+`, `#`) are encoded correctly.
19+
- The compute session lifecycle (resolve context → create → reuse/reset/teardown) is centralised in `_ComputeSessionCache`; `run_one_snippet` and the compute tools now share it, and `delete_session` was extracted as a reusable helper.
20+
321
## [1.1.0] - 2026-05-31
422

523
### Changed — BREAKING

README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ A Model Context Protocol (MCP) server for executing SAS code, training AutoML pr
44

55
## Features
66

7-
- 20+ Tools spanning the Analytics Life Cycle across SAS Viya
7+
- 30+ Tools spanning the Analytics Life Cycle across SAS Viya
88
- Prompt Templates for improving your SAS Code
99
- OAuth2 authentication with PKCE flow
1010
- HTTP-based MCP server compatible with MCP clients
@@ -135,7 +135,7 @@ The server validates the token against Viya's JWKS and uses it upstream as-is, b
135135
### Available Tools
136136

137137
#### Code Execution
138-
- **execute_sas_code**: Execute SAS code snippets and retrieve execution results (log and listing output)
138+
- **execute_sas_code**: Execute SAS code snippets and retrieve execution results (log and listing output). Runs in a reusable, per-user compute session that is kept warm across calls, so SAS state (WORK tables, macro variables, assigned librefs) persists between successive calls — use **reset_compute_session** to start fresh.
139139

140140
#### Data Discovery (CAS Management)
141141
- **list_cas_servers**: List available CAS servers
@@ -173,6 +173,13 @@ The server validates the token against Viya's JWKS and uses it upstream as-is, b
173173
- **list_models_and_decisions**: List published MAS modules
174174
- **score_data**: Score data against a published model
175175

176+
#### Compute Contexts & Code Execution
177+
- **list_compute_contexts**: List available compute contexts
178+
- **list_compute_libraries**: List the SAS libraries (librefs) assigned in a compute context
179+
- **list_compute_tables**: List the tables in a SAS library within a compute context
180+
- **list_compute_columns**: List the columns of a table in a SAS library
181+
- **reset_compute_session**: Delete the cached compute session for a context, discarding its SAS state and forcing a fresh session on the next call
182+
176183
### Prompt Templates
177184

178185
- **debug_sas_log**: Analyze SAS log for errors with root-cause explanations
@@ -293,7 +300,7 @@ Integration tests call every tool against a live Viya environment. They require
293300
./run_tests.sh --integration-only
294301
```
295302

296-
Every one of the 27 tools and 8 prompt templates has an integration test, enforced by the
303+
Every one of the 32 tools and 8 prompt templates has an integration test, enforced by the
297304
`test_every_tool_has_integration_coverage` / `test_every_prompt_has_integration_coverage`
298305
guards — adding a new tool or prompt without integration coverage fails the suite. The
299306
resource-dependent tests discover real targets on the instance: `score_data` scores the most
@@ -326,7 +333,7 @@ gh gist create reports/integration.xml # full XML as a
326333

327334
| File | Description |
328335
|---|---|
329-
| `tests/test_tool_payloads.py` | Payload assertions for all 27 tools (URL paths, JSON body, query params, headers) plus error-path coverage |
336+
| `tests/test_tool_payloads.py` | Payload assertions for all 32 tools (URL paths, JSON body, query params, headers) plus error-path coverage |
330337
| `tests/test_integration.py` | End-to-end workflow tests against a real Viya instance |
331338
| `tests/test_tools.py` | Unit tests for the generic Viya REST helpers in `viya_client` (`get_json`, `post_json`, `make_client`, …) |
332339
| `tests/test_viya_utils.py` | Unit tests for Viya compute session and job orchestration |

0 commit comments

Comments
 (0)