@granular-software/sdk 0.4.13 → 0.4.15
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/README.md +14 -12
- package/dist/cli/index.js +362 -75
- package/dist/index.d.mts +156 -12
- package/dist/index.d.ts +156 -12
- package/dist/index.js +173 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +173 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5613,6 +5613,19 @@ function normalizeUser(user) {
|
|
|
5613
5613
|
permissions: Array.isArray(user.permissions) ? user.permissions : []
|
|
5614
5614
|
};
|
|
5615
5615
|
}
|
|
5616
|
+
function normalizeEnvironmentData(environment) {
|
|
5617
|
+
const buildPolicy = environment.buildPolicy || environment.tracking || (environment.tagId ? { mode: "tag", tagId: environment.tagId } : { mode: "pinned", versionId: environment.versionId || environment.buildId });
|
|
5618
|
+
const environmentName = environment.environment || environment.envName || "prod";
|
|
5619
|
+
return {
|
|
5620
|
+
...environment,
|
|
5621
|
+
ontologyId: environment.ontologyId || environment.sandboxId,
|
|
5622
|
+
versionId: environment.versionId || environment.buildId,
|
|
5623
|
+
envName: environmentName,
|
|
5624
|
+
environment: environmentName,
|
|
5625
|
+
buildPolicy,
|
|
5626
|
+
tracking: environment.tracking || buildPolicy
|
|
5627
|
+
};
|
|
5628
|
+
}
|
|
5616
5629
|
var Environment = class extends Session {
|
|
5617
5630
|
envData;
|
|
5618
5631
|
_apiKey;
|
|
@@ -5631,10 +5644,26 @@ var Environment = class extends Session {
|
|
|
5631
5644
|
get sandboxId() {
|
|
5632
5645
|
return this.envData.sandboxId;
|
|
5633
5646
|
}
|
|
5647
|
+
/** The ontology ID */
|
|
5648
|
+
get ontologyId() {
|
|
5649
|
+
return this.envData.ontologyId || this.envData.sandboxId;
|
|
5650
|
+
}
|
|
5634
5651
|
/** The subject ID */
|
|
5635
5652
|
get subjectId() {
|
|
5636
5653
|
return this.envData.subjectId;
|
|
5637
5654
|
}
|
|
5655
|
+
/** The named environment slot, such as dev or prod */
|
|
5656
|
+
get envName() {
|
|
5657
|
+
return this.envData.envName;
|
|
5658
|
+
}
|
|
5659
|
+
/** The named environment slot, such as dev or prod */
|
|
5660
|
+
get environment() {
|
|
5661
|
+
return this.envData.environment || this.envData.envName;
|
|
5662
|
+
}
|
|
5663
|
+
/** The resolved ontology version backing this environment */
|
|
5664
|
+
get versionId() {
|
|
5665
|
+
return this.envData.versionId || this.envData.buildId;
|
|
5666
|
+
}
|
|
5638
5667
|
/** Internal Granular user identifier for this environment */
|
|
5639
5668
|
get granularId() {
|
|
5640
5669
|
return this.envData.subjectId;
|
|
@@ -5718,7 +5747,8 @@ var Environment = class extends Session {
|
|
|
5718
5747
|
"Authorization": `Bearer ${this._apiKey}`
|
|
5719
5748
|
},
|
|
5720
5749
|
body: JSON.stringify({
|
|
5721
|
-
reason: "sdk_disconnect_http_fallback"
|
|
5750
|
+
reason: "sdk_disconnect_http_fallback",
|
|
5751
|
+
sessionId: this.client.currentSessionId
|
|
5722
5752
|
})
|
|
5723
5753
|
}
|
|
5724
5754
|
);
|
|
@@ -6502,7 +6532,7 @@ var Environment = class extends Session {
|
|
|
6502
6532
|
return super.unpublishAllEffects();
|
|
6503
6533
|
}
|
|
6504
6534
|
};
|
|
6505
|
-
var Granular = class {
|
|
6535
|
+
var Granular = class _Granular {
|
|
6506
6536
|
apiKey;
|
|
6507
6537
|
apiUrl;
|
|
6508
6538
|
httpUrl;
|
|
@@ -6606,7 +6636,7 @@ var Granular = class {
|
|
|
6606
6636
|
throw new Error("connect() requires either userId, granularId, or a user object returned by recordUser().");
|
|
6607
6637
|
}
|
|
6608
6638
|
/**
|
|
6609
|
-
* Connect to
|
|
6639
|
+
* Connect to an ontology environment and establish a real-time session.
|
|
6610
6640
|
*
|
|
6611
6641
|
* Effects are registered at the sandbox level via `granular.registerEffect()`
|
|
6612
6642
|
* or `granular.registerEffects()`. Sessions pick up live availability from
|
|
@@ -6618,7 +6648,8 @@ var Granular = class {
|
|
|
6618
6648
|
* @example
|
|
6619
6649
|
* ```typescript
|
|
6620
6650
|
* const environment = await granular.connect({
|
|
6621
|
-
*
|
|
6651
|
+
* ontology: 'my-ontology',
|
|
6652
|
+
* environment: 'dev',
|
|
6622
6653
|
* userId: 'user_123',
|
|
6623
6654
|
* permissions: ['agent'],
|
|
6624
6655
|
* });
|
|
@@ -6638,17 +6669,28 @@ var Granular = class {
|
|
|
6638
6669
|
*
|
|
6639
6670
|
* console.log(await job.result); // 'Hello!'
|
|
6640
6671
|
* ```
|
|
6641
|
-
|
|
6672
|
+
*/
|
|
6642
6673
|
async connect(options) {
|
|
6643
6674
|
const clientId = options.clientId || `client_${Date.now()}`;
|
|
6675
|
+
const ontology = options.ontology;
|
|
6676
|
+
if (!ontology) {
|
|
6677
|
+
throw new Error("connect() requires `ontology`.");
|
|
6678
|
+
}
|
|
6679
|
+
const environmentName = options.environment;
|
|
6680
|
+
if (!environmentName) {
|
|
6681
|
+
throw new Error("connect() requires `environment`.");
|
|
6682
|
+
}
|
|
6683
|
+
const tagName = options.tagName?.trim() || void 0;
|
|
6644
6684
|
const user = await this.resolveConnectUser(options);
|
|
6645
|
-
const sandbox = await this.findOrCreateSandbox(
|
|
6685
|
+
const sandbox = await this.findOrCreateSandbox(ontology);
|
|
6646
6686
|
for (const profileName of user.permissions) {
|
|
6647
6687
|
const profileId = await this.ensurePermissionProfile(sandbox.sandboxId, profileName);
|
|
6648
6688
|
await this.ensureAssignment(user.granularId, sandbox.sandboxId, profileId);
|
|
6649
6689
|
}
|
|
6650
6690
|
const envData = await this.environments.create(sandbox.sandboxId, {
|
|
6651
6691
|
subjectId: user.granularId,
|
|
6692
|
+
environment: environmentName,
|
|
6693
|
+
tagName,
|
|
6652
6694
|
permissionProfileId: null
|
|
6653
6695
|
});
|
|
6654
6696
|
await this.activateEnvironment(envData.environmentId);
|
|
@@ -6660,6 +6702,120 @@ var Granular = class {
|
|
|
6660
6702
|
initialHeap: options.initialHeap
|
|
6661
6703
|
})
|
|
6662
6704
|
});
|
|
6705
|
+
return this.bindWebSocketEnvironment(envData, clientId, session);
|
|
6706
|
+
}
|
|
6707
|
+
/**
|
|
6708
|
+
* List active (open) sessions for an environment — each session is one agent conversation thread.
|
|
6709
|
+
*/
|
|
6710
|
+
async listOpenSessions(filters) {
|
|
6711
|
+
return this.listSessionsForEnvironment(filters.environmentId, "active");
|
|
6712
|
+
}
|
|
6713
|
+
/**
|
|
6714
|
+
* List closed sessions for an environment (conversations that have disconnected).
|
|
6715
|
+
*/
|
|
6716
|
+
async listClosedSessions(filters) {
|
|
6717
|
+
return this.listSessionsForEnvironment(filters.environmentId, "closed");
|
|
6718
|
+
}
|
|
6719
|
+
async listSessionsForEnvironment(environmentId, status) {
|
|
6720
|
+
const query = new URLSearchParams({ environmentId, status });
|
|
6721
|
+
const res = await this.request(
|
|
6722
|
+
`/control/sessions?${query.toString()}`
|
|
6723
|
+
);
|
|
6724
|
+
const items = Array.isArray(res.items) ? res.items : [];
|
|
6725
|
+
return items.map((row) => this.normalizeConversationSession(row));
|
|
6726
|
+
}
|
|
6727
|
+
normalizeConversationSession(row) {
|
|
6728
|
+
const sessionId = String(row.sessionId ?? row.session_id ?? "");
|
|
6729
|
+
const environmentId = String(row.environmentId ?? row.environment_id ?? "");
|
|
6730
|
+
return {
|
|
6731
|
+
sessionId,
|
|
6732
|
+
tenantId: row.tenantId != null ? String(row.tenantId) : void 0,
|
|
6733
|
+
environmentId,
|
|
6734
|
+
versionId: row.versionId != null ? String(row.versionId) : null,
|
|
6735
|
+
docId: String(row.docId ?? row.doc_id ?? ""),
|
|
6736
|
+
status: row.status || "active",
|
|
6737
|
+
createdAt: _Granular.coerceIsoDate(row.createdAt ?? row.created_at),
|
|
6738
|
+
lastSeenAt: _Granular.coerceIsoDate(row.lastSeenAt ?? row.last_seen_at),
|
|
6739
|
+
summary: row.summary != null ? String(row.summary) : null,
|
|
6740
|
+
summaryUpdatedAt: row.summaryUpdatedAt != null || row.summary_updated_at != null ? _Granular.coerceIsoDate(row.summaryUpdatedAt ?? row.summary_updated_at) : null,
|
|
6741
|
+
subjectId: row.subjectId != null ? String(row.subjectId) : null,
|
|
6742
|
+
jobCount: typeof row.jobCount === "number" ? row.jobCount : void 0,
|
|
6743
|
+
toolCallCount: typeof row.toolCallCount === "number" ? row.toolCallCount : void 0
|
|
6744
|
+
};
|
|
6745
|
+
}
|
|
6746
|
+
static coerceIsoDate(value) {
|
|
6747
|
+
if (value instanceof Date) {
|
|
6748
|
+
return value.toISOString();
|
|
6749
|
+
}
|
|
6750
|
+
if (typeof value === "number") {
|
|
6751
|
+
return new Date(value).toISOString();
|
|
6752
|
+
}
|
|
6753
|
+
if (typeof value === "string") {
|
|
6754
|
+
return value;
|
|
6755
|
+
}
|
|
6756
|
+
return (/* @__PURE__ */ new Date(0)).toISOString();
|
|
6757
|
+
}
|
|
6758
|
+
/**
|
|
6759
|
+
* Create a new session (conversation) for an existing environment and connect to it.
|
|
6760
|
+
* The runtime graph is shared across all sessions for the same environment.
|
|
6761
|
+
*/
|
|
6762
|
+
async createSession(options) {
|
|
6763
|
+
const clientId = options.clientId || `client_${Date.now()}`;
|
|
6764
|
+
await this.activateEnvironment(options.environmentId);
|
|
6765
|
+
const envData = await this.environments.get(options.environmentId);
|
|
6766
|
+
const session = await this.request("/ws/sessions", {
|
|
6767
|
+
method: "POST",
|
|
6768
|
+
body: JSON.stringify({
|
|
6769
|
+
environmentId: options.environmentId,
|
|
6770
|
+
clientId,
|
|
6771
|
+
initialHeap: options.initialHeap
|
|
6772
|
+
})
|
|
6773
|
+
});
|
|
6774
|
+
return this.bindWebSocketEnvironment(envData, clientId, session);
|
|
6775
|
+
}
|
|
6776
|
+
/**
|
|
6777
|
+
* Connect to an existing open session (same conversation thread) using a freshly minted WebSocket token.
|
|
6778
|
+
*/
|
|
6779
|
+
async connectSession(options) {
|
|
6780
|
+
const clientId = options.clientId || `client_${Date.now()}`;
|
|
6781
|
+
const minted = await this.request(`/ws/sessions/${encodeURIComponent(options.sessionId)}/token`, {
|
|
6782
|
+
method: "POST",
|
|
6783
|
+
body: JSON.stringify({})
|
|
6784
|
+
});
|
|
6785
|
+
const envData = await this.environments.get(minted.environmentId);
|
|
6786
|
+
return this.bindWebSocketEnvironment(envData, clientId, minted);
|
|
6787
|
+
}
|
|
6788
|
+
/**
|
|
6789
|
+
* Mark a session closed in the control plane. If `environment` is the connected handle for that
|
|
6790
|
+
* `sessionId`, disconnects the WebSocket so the runtime tears down cleanly.
|
|
6791
|
+
*/
|
|
6792
|
+
async closeSession(sessionId, environment) {
|
|
6793
|
+
if (environment && environment.sessionId === sessionId) {
|
|
6794
|
+
await environment.disconnect();
|
|
6795
|
+
return;
|
|
6796
|
+
}
|
|
6797
|
+
await this.request(`/control/sessions/${encodeURIComponent(sessionId)}`, {
|
|
6798
|
+
method: "PATCH",
|
|
6799
|
+
body: JSON.stringify({
|
|
6800
|
+
status: "closed",
|
|
6801
|
+
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6802
|
+
})
|
|
6803
|
+
});
|
|
6804
|
+
}
|
|
6805
|
+
/**
|
|
6806
|
+
* Re-open a closed session in the index and connect to its existing runtime document.
|
|
6807
|
+
*/
|
|
6808
|
+
async reopenSession(sessionId, options) {
|
|
6809
|
+
await this.request(`/control/sessions/${encodeURIComponent(sessionId)}`, {
|
|
6810
|
+
method: "PATCH",
|
|
6811
|
+
body: JSON.stringify({
|
|
6812
|
+
status: "active",
|
|
6813
|
+
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6814
|
+
})
|
|
6815
|
+
});
|
|
6816
|
+
return this.connectSession({ sessionId, clientId: options?.clientId });
|
|
6817
|
+
}
|
|
6818
|
+
async bindWebSocketEnvironment(envData, clientId, session) {
|
|
6663
6819
|
const client = new WSClient({
|
|
6664
6820
|
url: session.wsUrl,
|
|
6665
6821
|
sessionId: session.sessionId,
|
|
@@ -7083,16 +7239,22 @@ var Granular = class {
|
|
|
7083
7239
|
const result = await this.request(
|
|
7084
7240
|
`/control/sandboxes/${sandboxId}/environments`
|
|
7085
7241
|
);
|
|
7086
|
-
return result.items;
|
|
7242
|
+
return result.items.map(normalizeEnvironmentData);
|
|
7087
7243
|
},
|
|
7088
7244
|
get: async (environmentId) => {
|
|
7089
|
-
return
|
|
7245
|
+
return normalizeEnvironmentData(
|
|
7246
|
+
await this.request(`/control/environments/${environmentId}`)
|
|
7247
|
+
);
|
|
7090
7248
|
},
|
|
7091
7249
|
create: async (sandboxId, data) => {
|
|
7092
|
-
|
|
7250
|
+
const environmentName = data.environment || data.envName;
|
|
7251
|
+
return normalizeEnvironmentData(await this.request(`/control/sandboxes/${sandboxId}/environments`, {
|
|
7093
7252
|
method: "POST",
|
|
7094
|
-
body: JSON.stringify(
|
|
7095
|
-
|
|
7253
|
+
body: JSON.stringify({
|
|
7254
|
+
...data,
|
|
7255
|
+
envName: environmentName
|
|
7256
|
+
})
|
|
7257
|
+
}));
|
|
7096
7258
|
},
|
|
7097
7259
|
delete: async (environmentId) => {
|
|
7098
7260
|
return this.request(`/control/environments/${environmentId}`, {
|