c52d8d0171
I was wrong. AVEVA Tech Note 537 ("Creating an Application Object Script
Using GRAccess", April 2008) documents the supported pattern:
ConfigurableAttributes[<script>.<field>].SetValue(MxValue) inside a
CheckOut/Save/CheckIn cycle. graccesscli's existing
FindAttributeForMutation already follows this — writes to MxCategoryPackageOnly_Lockable
script-text fields persist correctly.
The earlier "writeback gap" diagnosis was a phantom caused by a reader-side
issue. `object attribute value get` against a script body returns
"Supported: False / Attribute value is not exposed" because
MxValueDetails uses a case-sensitive `ReadProperty(attr, "Value")` lookup
plus an accessor probe (GetBoolean -> GetInteger -> GetFloat -> GetDouble
-> GetString) that can fall through silently for some MxValue shapes. The
COM-side property is exposed as `value` (lowercase), readable as
`attr.value.GetString()` -- which the live probe at
`analysis/ide-edit-investigation/probe_setvalue/` does and confirms the
post-write content matches the marker exactly.
Live verification on $TestMachine.UpdateTestChangingInt.DeclarationsText
and $DelmiaReceiver.ProcessRecipe.{ExecuteText,DeclarationsText}:
=== verdict ===
marker landed on same-proxy ConfigurableAttributes: True
marker landed on same-proxy Attributes : True
marker landed on fresh-proxy ConfigurableAttributes: True
marker landed on fresh-proxy Attributes : True
The probe also confirmed that two earlier graccesscli `object scripts set`
invocations (which I had wrongly believed failed) had persisted -- the
marker text I wrote previously was still on disk in
ProcessRecipe.{ExecuteText,DeclarationsText} when read directly via
attr.value.GetString(). The probe restored both fields to their original
values.
This commit:
- Updates the misleading [Command(...)] / [CommandOption(...)]
descriptions in GRAccessSurfaceCommands.cs back to honest versions
citing TN-537.
- Restores the --file-using examples for `object scripts set` and
`object scripts create` across script-editing.md, llm-integration.md,
usage.md, and zb-testmachine.md.
- Removes the test that asserted the (wrong) EnsureMutableViaSetValue
guard. Re-aims ScriptCommandDescriptions_… at the corrected wording.
- Removes two leftover EnsureMutableViaSetValue calls in the trigger-period
/ trigger-type write paths (both targeted MxCategoryWriteable_C_Lockable
attributes; would never have fired even if the helper still existed).
- Adds analysis/ide-edit-investigation/REPORT.md (replacing the earlier
wrong report) plus the probe sources under probe_setvalue/.
The MxValueDetails reader gap (case-sensitive ReadProperty + accessor
probe) is a real follow-up: `object attribute value get` should
case-insensitively read `value` and try GetString first when the
underlying MxValue.DataType is MxString. Out of scope here -- that's a
separate, smaller fix.
Test count delta: 67 -> 66 (-2 wrong tests, +1 corrected description test).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
173 lines
8.6 KiB
Markdown
173 lines
8.6 KiB
Markdown
# LLM Integration Guide
|
|
|
|
This document is the implemented machine-facing contract for using `graccess_cli` as an LLM automation layer for AVEVA/Wonderware System Platform IDE work through GRAccess.
|
|
|
|
The CLI still preserves legacy human output and existing `--json` shapes. LLMs should use `--llm-json` for a stable envelope.
|
|
|
|
## Stable Envelope
|
|
|
|
Galaxy-bound routed commands and LLM helper commands accept `--llm-json`.
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"command": "object snapshot",
|
|
"galaxy": "ZB",
|
|
"target": "TestMachine",
|
|
"data": {},
|
|
"commandResult": null,
|
|
"warnings": [],
|
|
"unavailable": [],
|
|
"error": null,
|
|
"exitCode": 0
|
|
}
|
|
```
|
|
|
|
Failures use the same envelope with `success=false`, `error`, and `exitCode`.
|
|
|
|
## Discovery
|
|
|
|
Use capabilities before generating plans:
|
|
|
|
```powershell
|
|
graccess capabilities --json
|
|
graccess capabilities --llm-json
|
|
```
|
|
|
|
The capability registry is code-backed, not scraped from prose. It returns command name, dispatcher command/subcommand, argument metadata, mutation status, session routing support, confirmation target rule, and output schema name.
|
|
|
|
## Read Workflow
|
|
|
|
Prefer session mode for repeated reads:
|
|
|
|
```powershell
|
|
graccess session start --galaxy ZB --node .
|
|
graccess object snapshot --galaxy ZB --name TestMachine --type template --llm-json
|
|
```
|
|
|
|
`object snapshot` includes object details, all attributes, configurable attributes, extended attributes, relationships, lineage, children, contained objects, package-backed attribute values/script bodies where available, and `Unavailable` entries for COM-backed sections that cannot be read safely.
|
|
|
|
Useful read commands:
|
|
|
|
```powershell
|
|
graccess object get --galaxy ZB --name TestMachine --type template --llm-json
|
|
graccess object lineage --galaxy ZB --name '$TestMachine' --type template --llm-json
|
|
graccess object children --galaxy ZB --name '$TestMachine' --type template --llm-json
|
|
graccess object attribute value get --galaxy ZB --name TestMachine --type template --attribute Description --llm-json
|
|
graccess object scripts list --galaxy ZB --name TestMachine --type template --llm-json
|
|
graccess object scripts get --galaxy ZB --name TestMachine --type template --script UpdateTestChangingInt --llm-json
|
|
```
|
|
|
|
The CLI tries direct GRAccess reads first. If direct GRAccess does not expose inheritance, attribute values, or script bodies, read commands may export the target object to a temporary `.aaPKG`, parse textual/package entries, recurse into nested package archives, parse binary UTF-16 script extension records, and delete the temp files. SQL Server repository reads are not part of normal CLI behavior and should only be used for development verification/debugging.
|
|
|
|
Script body access is adapter-dependent. For `ScriptExtension` objects, a bare script name maps to `.ExecuteText`; `object scripts set --file <path>` writes the matching script body attribute through GRAccess. Mutating script and attribute commands prefer `ConfigurableAttributes[...]` before `Attributes[...]`, because script extension settings such as `TriggerPeriod`, `TriggerType`, `Expression`, and `ExecuteText` are configuration attributes per AVEVA Tech Note 537 ("Creating an Application Object Script Using GRAccess"). If neither direct GRAccess nor the package fallback exposes body text on a read, script read commands return structured unavailable details — but writes via the TN-537 pattern persist; round-trip evidence is in `analysis/ide-edit-investigation/probe_setvalue/`.
|
|
|
|
Use the script settings wrapper for IDE-style script configuration:
|
|
|
|
```powershell
|
|
graccess object scripts settings set --galaxy ZB --name '$TestMachine' --type template --script UpdateTestChangingInt --trigger-period-ms 500 --lock-trigger-period --confirm --confirm-target '$TestMachine' --llm-json
|
|
```
|
|
|
|
Use the create wrapper for new object-level script extensions:
|
|
|
|
```powershell
|
|
graccess object scripts create --galaxy ZB --name '$MyTemplate' --type template --script OnScan --file OnScan.txt --trigger-type Periodic --trigger-period-ms 1000 --confirm --confirm-target '$MyTemplate' --llm-json
|
|
```
|
|
|
|
## Inheritance And Embedded Objects
|
|
|
|
For template families, model inheritance and containment explicitly. Do not rely on a single field being populated by every GRAccess version.
|
|
|
|
```powershell
|
|
graccess object snapshot --galaxy ZB --name '$TestMachine' --type template --llm-json
|
|
graccess object lineage --galaxy ZB --name '$TestMachine' --type template --llm-json
|
|
graccess object children --galaxy ZB --name '$TestMachine' --type template --llm-json
|
|
graccess object query-condition --galaxy ZB --type all --condition derivedOrInstantiatedFrom --value '$gMachine' --llm-json
|
|
graccess object query-condition --galaxy ZB --type all --condition basedOn --value '$gMachine' --llm-json
|
|
graccess object query-condition --galaxy ZB --type all --condition containedBy --value '$TestMachine' --llm-json
|
|
```
|
|
|
|
Read `data.Lineage`, `data.Children`, `data.ContainedObjects`, `data.Object.DerivedFrom`, `data.Object.BasedOn`, `ContainedName`, and `HierarchicalName` when available. The documented `ZB` `$TestMachine` family is an example: `$TestMachine` extends `$gMachine`, while `$TestMachine.DelmiaReceiver` and `$TestMachine.MESReceiver` are contained embedded templates.
|
|
|
|
Create derived templates and instances with contained objects when the family requires embedded children:
|
|
|
|
```powershell
|
|
graccess template derive --galaxy ZB --name '$gMachine' --type template --new-name '$MyMachine' --confirm --confirm-target '$gMachine' --llm-json
|
|
graccess template instantiate --galaxy ZB --name '$TestMachine' --type template --new-name TestMachine_021 --create-contained --confirm --confirm-target '$TestMachine' --llm-json
|
|
```
|
|
|
|
Edit contained child templates or instances by targeting their own object names, such as `$TestMachine.DelmiaReceiver` or `DelmiaReceiver_001`, and use normal checkout/save/checkin safety.
|
|
|
|
## Validation And Batch
|
|
|
|
Per-command dry-run validates command shape and confirmation without calling mutating GRAccess methods:
|
|
|
|
```powershell
|
|
graccess object attribute value set --galaxy ZB --name TestMachine --type template --attribute Description --value Updated --data-type string --confirm --confirm-target TestMachine --dry-run --llm-json
|
|
```
|
|
|
|
Plan validation:
|
|
|
|
```powershell
|
|
graccess validate --request plan.json --llm-json
|
|
```
|
|
|
|
Batch validation or execution:
|
|
|
|
```powershell
|
|
graccess batch --file plan.json --mode validate --llm-json
|
|
graccess batch --file plan.json --mode execute --llm-json
|
|
```
|
|
|
|
Plan shape:
|
|
|
|
```json
|
|
{
|
|
"Galaxy": "ZB",
|
|
"Node": ".",
|
|
"Commands": [
|
|
{
|
|
"Command": "object checkout",
|
|
"Args": {
|
|
"name": "TestMachine",
|
|
"type": "template",
|
|
"confirm": true,
|
|
"confirm-target": "TestMachine"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
Every mutating step must include its own `confirm=true` and exact `confirm-target`. There is no global mutation confirmation. Batch execute stops on first failure.
|
|
|
|
## IDE Intent Wrappers
|
|
|
|
Use intent-level commands instead of generic property edits when possible:
|
|
|
|
```powershell
|
|
graccess area list --galaxy ZB --llm-json
|
|
graccess area create --galaxy ZB --template '$Area' --name Area_Test --confirm --confirm-target '$Area' --llm-json
|
|
graccess engine list --galaxy ZB --llm-json
|
|
graccess engine create --galaxy ZB --template '$AppEngine' --name AppEngine_Test --confirm --confirm-target '$AppEngine' --llm-json
|
|
graccess instance assign-area --galaxy ZB --name TestMachine_001 --area Area_Test --confirm --confirm-target TestMachine_001 --llm-json
|
|
graccess instance assign-engine --galaxy ZB --name TestMachine_001 --engine AppEngine_Test --confirm --confirm-target TestMachine_001 --llm-json
|
|
graccess instance assign-container --galaxy ZB --name TestMachine_001 --container ParentObject --confirm --confirm-target TestMachine_001 --llm-json
|
|
graccess io assign --galaxy ZB --name TestMachine_001 --attribute DeviceAddress --value D100 --confirm --confirm-target TestMachine_001 --llm-json
|
|
```
|
|
|
|
`object set --property area|host|container|toolset|security-group` attempts to resolve the named GRAccess object first, then falls back to raw string assignment for version-specific setters.
|
|
|
|
## Safety Rules
|
|
|
|
1. Start with `capabilities` and read-only snapshots.
|
|
2. Do not mutate without an exact object or file target.
|
|
3. Never use wildcard bulk mutation in production.
|
|
4. Use `--dry-run --llm-json` before mutation plans.
|
|
5. Snapshot before editing and re-read after editing.
|
|
6. Stop after the first failed mutation or `CommandResult.Successful=false`.
|
|
7. Treat missing or unavailable fields as unknown, not false.
|
|
8. Prefer test objects or derived templates before production targets.
|
|
9. Use session mode for repeated galaxy-bound commands.
|
|
10. Use deployment commands only when the user explicitly names targets.
|