@sdlcagent/agent-sdk 1.0.0 → 1.0.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 (2) hide show
  1. package/README.md +136 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # @sdlcagent/agent-sdk
2
+
3
+ Contract library for Sage platform agents. Provides the HTTP server scaffold, the
4
+ `ContextEnvelope` / `ResultEnvelope` contract types (validated with Zod), structured
5
+ logging, and error types that every Sage agent runtime is expected to implement
6
+ against.
7
+
8
+ ## Install
9
+
10
+ ```
11
+ npm install @sdlcagent/agent-sdk
12
+ ```
13
+
14
+ ## Quick start
15
+
16
+ An agent implements a single handler — `(ctx: ContextEnvelope) => Promise<ResultEnvelope>`
17
+ — and hands it to `AgentServer`, which exposes `/invoke`, `/health`, `/ready`, and `/start`
18
+ over HTTP.
19
+
20
+ ```ts
21
+ import { AgentServer, type AgentHandler } from '@sdlcagent/agent-sdk';
22
+ import manifest from './agent.manifest.json';
23
+
24
+ const handler: AgentHandler = async (ctx) => {
25
+ // ctx is a validated ContextEnvelope
26
+ return {
27
+ status: 'SUCCEEDED',
28
+ summary: 'Did the thing',
29
+ output_data: { result: 42 },
30
+ };
31
+ };
32
+
33
+ AgentServer.start({ manifest, handler });
34
+ ```
35
+
36
+ `agent.manifest.json` must contain at least `agent_id` and `version`.
37
+
38
+ ### Endpoints
39
+
40
+ | Method | Path | Purpose |
41
+ | ------ | --------- | ------------------------------------------------------------------- |
42
+ | POST | `/invoke` | Parses the request body as a `ContextEnvelope`, runs `handler`, validates and returns a `ResultEnvelope`. Never throws over HTTP — failures come back as `status: "FAILED"` with a 200. |
43
+ | GET | `/health` | Returns `{ status, agent_id, version, image_digest }`. |
44
+ | GET | `/ready` | Returns `{ status: "ready" }`. |
45
+ | POST | `/start` | Injects per-tenant runtime env vars (`{ env_vars: {...} }`) before the first `/invoke`. |
46
+
47
+ ### Configuration (env vars)
48
+
49
+ - `AGENT_PORT` — port to listen on (default `8080`)
50
+ - `AGENT_TIMEOUT_MS` — per-invocation handler timeout (default `300000`)
51
+ - `LOG_LEVEL` — `debug` | `info` | `warn` | `error` (default `info`)
52
+
53
+ A `.env` file in the process working directory is loaded automatically on import.
54
+
55
+ ## Envelopes
56
+
57
+ ### ContextEnvelope
58
+
59
+ The validated input to every agent invocation (`parseContextEnvelope` is called
60
+ internally by `AgentServer`, but is exported for standalone use):
61
+
62
+ ```ts
63
+ import { parseContextEnvelope, type ContextEnvelope } from '@sdlcagent/agent-sdk';
64
+
65
+ const ctx: ContextEnvelope = parseContextEnvelope(req.body);
66
+ ```
67
+
68
+ Key fields: `org_id`, `project_id`, `team_id`, `run_id`, `step_id`, `workflow_type`,
69
+ `run_mode` (`'CREATE' | 'MODIFY_ENHANCE'`), `trigger`, `work_item_context`,
70
+ `policy_snapshot`, `prompt_refs`, `redaction_profile`, `memory_refs?`, `agent_config`,
71
+ `log_callback_url`, `step_token`.
72
+
73
+ Throws `ContextEnvelopeParseError` (code `CONTEXT_INVALID`) on validation failure.
74
+
75
+ ### ResultEnvelope
76
+
77
+ The validated output every handler must resolve to:
78
+
79
+ ```ts
80
+ import { validateResultEnvelope, type ResultEnvelope } from '@sdlcagent/agent-sdk';
81
+ ```
82
+
83
+ Key fields: `status` (`'SUCCEEDED' | 'FAILED' | 'HITL_REQUIRED'`), `summary`,
84
+ `output_data?`, `action_requests?`, `artifacts_created?`, `critic_signal?`,
85
+ `hitl_reason?`, `hitl_options?`, `remember?`, `agent_summary?`, `next_step_hint?`,
86
+ `metrics?`.
87
+
88
+ Throws `ResultEnvelopeValidationError` (code `OUTPUT_BUILD_FAILED`) on validation failure.
89
+
90
+ ## Errors
91
+
92
+ `AgentError` is the base error type for agent handlers, carrying a stable `code`,
93
+ a `retryable` flag (derived automatically per code unless overridden), and an
94
+ optional `detail` payload:
95
+
96
+ ```ts
97
+ import { AgentError } from '@sdlcagent/agent-sdk';
98
+
99
+ throw new AgentError('MODEL_ERROR', 'LLM returned garbage');
100
+ ```
101
+
102
+ Codes: `CONTEXT_INCOMPLETE`, `CONTEXT_INVALID`, `MODEL_ERROR`, `MODEL_REFUSED`,
103
+ `ACTION_FORBIDDEN`, `WORK_ITEM_PARSE_ERROR`, `OUTPUT_BUILD_FAILED`, `TIMEOUT`,
104
+ `UNEXPECTED`, and the Model Rail gateway codes `INVALID_REQUEST`,
105
+ `BUDGET_EXCEEDED`, `PURPOSE_NOT_ALLOWED`, `POLICY_NOT_FOUND`. Any error thrown out
106
+ of a handler is caught by `AgentServer` and turned into a `FAILED` `ResultEnvelope`.
107
+
108
+ ## Logging
109
+
110
+ `logger` writes structured JSON lines to stdout and threads run context
111
+ (`run_id`, `org_id`, `project_id`, `step_id`, `agent_id`) through
112
+ `AsyncLocalStorage`, so any log call inside a handler automatically carries it:
113
+
114
+ ```ts
115
+ import { logger } from '@sdlcagent/agent-sdk';
116
+
117
+ logger.info({ event: 'DOING_WORK' });
118
+
119
+ await logger.time('llm_invoke', async () => {
120
+ // logs STEP_START / STEP_END / STEP_ERROR with duration_ms
121
+ });
122
+ ```
123
+
124
+ `emitLog(ctx, phase, message, opts?)` posts a log line to the run's
125
+ `log_callback_url` (best-effort, swallows errors) using one of the fixed
126
+ `AGENT_PHASES`: `context_parse`, `llm_invoke`, `llm_complete`, `critic_tier1`,
127
+ `critic_tier2`, `tool_call`, `artifact_write`, `result_emit`.
128
+
129
+ ## Development
130
+
131
+ ```
132
+ npm run build # compile to dist/
133
+ npm test # run the jest suite
134
+ npm run test:coverage
135
+ npm run typecheck
136
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdlcagent/agent-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Contract library for Sage platform agents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",