@eng-ai/sdk 2.8.5 → 2.8.7

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/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to `@eng-ai/sdk` will be documented in this file.
4
4
 
5
+ ## 2.8.7 - 2026-04-22
6
+
7
+ ### Added
8
+
9
+ - External SDK history APIs (v2) in JS SDK:
10
+ - `listSdkSessions({ limit?, offset?, projectId? })`
11
+ - `getSdkSession(sessionId)`
12
+ - SDK invoke responses now include `request.session_id`, enabling integrations to persist and continue the same conversation thread safely.
13
+ - CLI `eng-ai` now supports external SDK history inspection:
14
+ - `sdk sessions list`
15
+ - `sdk sessions get --session-id <id>`
16
+
17
+ ### Changed
18
+
19
+ - SDK conversations created through `/api/v2/sdk` are now persisted server-side with explicit source metadata (`session_source="sdk"` and `metadata.source="sdk"`), making them queryable via the external API.
20
+
5
21
  ## 2.8.5 - 2026-04-14
6
22
 
7
23
  ### Changed
package/README.md CHANGED
@@ -36,6 +36,7 @@ const response =
36
36
 
37
37
  console.log(response.result.content);
38
38
  console.log(response.normative?.citations ?? []);
39
+ console.log(response.request.session_id);
39
40
 
40
41
  // Recommended error handling
41
42
  try {
@@ -73,6 +74,27 @@ const projects = await client.listProjects({ limit: 10, offset: 0 });
73
74
  console.log(project.id, projects.length);
74
75
  ```
75
76
 
77
+ SDK conversation history:
78
+
79
+ ```js
80
+ const first = await client.invokeAgent({
81
+ message: "Explique o conceito de talude",
82
+ });
83
+
84
+ const sessionId = first.request.session_id;
85
+ const second = await client.invokeAgent({
86
+ sessionId,
87
+ message: "Continue e detalhe os tipos de contenção",
88
+ });
89
+
90
+ const sessions = await client.listSdkSessions({ limit: 10 });
91
+ const session = await client.getSdkSession(sessionId);
92
+
93
+ console.log(second.request.session_id);
94
+ console.log(sessions.map((item) => item.id));
95
+ console.log(session.messages.length);
96
+ ```
97
+
76
98
  Task autonomy mode by project:
77
99
 
78
100
  ```js
@@ -182,6 +204,11 @@ Supported automation plan actions:
182
204
  - `rejectAutomationPlan(projectId, planId, note?, { idempotencyKey? })`
183
205
  - `applyAutomationPlan(projectId, planId, { idempotencyKey? })`
184
206
 
207
+ Supported SDK history actions:
208
+
209
+ - `listSdkSessions({ limit?, offset?, projectId? })`
210
+ - `getSdkSession(sessionId)`
211
+
185
212
  Supported project knowledge actions:
186
213
 
187
214
  - `getProjectIntakeStatus(projectId)`
@@ -225,6 +252,8 @@ await client.updateProfile({
225
252
  CLI (`eng-ai`) included in package:
226
253
 
227
254
  ```bash
255
+ ENG_AI_API_KEY=sk_xxx eng-ai sdk sessions list --limit 10
256
+ ENG_AI_API_KEY=sk_xxx eng-ai sdk sessions get --session-id <id>
228
257
  ENG_AI_API_KEY=sk_xxx eng-ai projects autonomy set --project-id <id> --mode approval_required
229
258
  ENG_AI_API_KEY=sk_xxx eng-ai plans actionable list --limit 30
230
259
  ENG_AI_API_KEY=sk_xxx eng-ai plans approve --project-id <id> --plan-id <id> --note "Approved"
package/bin/eng-ai.js CHANGED
@@ -59,6 +59,8 @@ function printHelp() {
59
59
  ENG-AI SDK CLI
60
60
 
61
61
  Usage:
62
+ eng-ai sdk sessions list [--limit <n>] [--offset <n>] [--project-id <id>]
63
+ eng-ai sdk sessions get --session-id <id>
62
64
  eng-ai projects autonomy set --project-id <id> --mode <approval_required|approval_delete_only|full_autonomy> [--idempotency-key <key>]
63
65
  eng-ai plans actionable list [--limit <n>]
64
66
  eng-ai plans approve --project-id <id> --plan-id <id> [--note <text>] [--idempotency-key <key>]
@@ -136,6 +138,37 @@ async function runProjectsCommand(client, subTokens, options) {
136
138
  );
137
139
  }
138
140
 
141
+ async function runSdkCommand(client, subTokens, options) {
142
+ const section = String(subTokens[0] || "").trim().toLowerCase();
143
+ const action = String(subTokens[1] || "").trim().toLowerCase();
144
+
145
+ if (section !== "sessions" || !action) {
146
+ throw new Error("Unsupported sdk command. Use: sdk sessions list|get");
147
+ }
148
+
149
+ if (action === "list") {
150
+ const sessions = await client.listSdkSessions({
151
+ limit: options.limit !== undefined ? toPositiveInt(options.limit, 20) : undefined,
152
+ offset: options.offset !== undefined ? Math.max(0, Number(options.offset) || 0) : undefined,
153
+ projectId: options["project-id"],
154
+ });
155
+ console.log(JSON.stringify(sessions, null, 2));
156
+ return;
157
+ }
158
+
159
+ if (action === "get") {
160
+ const sessionId = options["session-id"];
161
+ if (!sessionId) {
162
+ throw new Error("Missing required option: --session-id");
163
+ }
164
+ const session = await client.getSdkSession(sessionId);
165
+ console.log(JSON.stringify(session, null, 2));
166
+ return;
167
+ }
168
+
169
+ throw new Error("Unsupported sdk command. Use: sdk sessions list|get");
170
+ }
171
+
139
172
  function printPlansSummary(plans) {
140
173
  const rows = Array.isArray(plans) ? plans : [];
141
174
  const formatted = rows.map((plan) => ({
@@ -327,6 +360,10 @@ async function main() {
327
360
  await runProjectsCommand(client, tokens.slice(1), options);
328
361
  return;
329
362
  }
363
+ if (command === "sdk") {
364
+ await runSdkCommand(client, tokens.slice(1), options);
365
+ return;
366
+ }
330
367
  if (command === "plans") {
331
368
  await runPlansCommand(client, tokens.slice(1), options);
332
369
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eng-ai/sdk",
3
- "version": "2.8.5",
3
+ "version": "2.8.7",
4
4
  "description": "Official JavaScript SDK for ENG-AI External API v2",
5
5
  "type": "module",
6
6
  "main": "./src/client.js",
package/src/client.js CHANGED
@@ -437,6 +437,27 @@ export class EngAIClient {
437
437
  });
438
438
  }
439
439
 
440
+ async listSdkSessions(options = {}) {
441
+ const query = new URLSearchParams();
442
+ if (options.limit !== undefined) query.set("limit", String(options.limit));
443
+ if (options.offset !== undefined) query.set("offset", String(options.offset));
444
+ if (options.projectId ?? options.project_id) {
445
+ query.set("project_id", String(options.projectId ?? options.project_id));
446
+ }
447
+ const suffix = query.toString() ? `?${query.toString()}` : "";
448
+
449
+ return await this._request(`/sdk/sessions${suffix}`, {
450
+ method: "GET",
451
+ });
452
+ }
453
+
454
+ async getSdkSession(sessionId) {
455
+ const normalizedSessionId = this._requireNonEmptyString(sessionId, "sessionId");
456
+ return await this._request(`/sdk/sessions/${encodeURIComponent(normalizedSessionId)}`, {
457
+ method: "GET",
458
+ });
459
+ }
460
+
440
461
  async createProject(payload) {
441
462
  if (!String(payload?.name || "").trim()) {
442
463
  throw new EngAIError("name is required for createProject", {