@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.mjs
CHANGED
|
@@ -5591,6 +5591,19 @@ function normalizeUser(user) {
|
|
|
5591
5591
|
permissions: Array.isArray(user.permissions) ? user.permissions : []
|
|
5592
5592
|
};
|
|
5593
5593
|
}
|
|
5594
|
+
function normalizeEnvironmentData(environment) {
|
|
5595
|
+
const buildPolicy = environment.buildPolicy || environment.tracking || (environment.tagId ? { mode: "tag", tagId: environment.tagId } : { mode: "pinned", versionId: environment.versionId || environment.buildId });
|
|
5596
|
+
const environmentName = environment.environment || environment.envName || "prod";
|
|
5597
|
+
return {
|
|
5598
|
+
...environment,
|
|
5599
|
+
ontologyId: environment.ontologyId || environment.sandboxId,
|
|
5600
|
+
versionId: environment.versionId || environment.buildId,
|
|
5601
|
+
envName: environmentName,
|
|
5602
|
+
environment: environmentName,
|
|
5603
|
+
buildPolicy,
|
|
5604
|
+
tracking: environment.tracking || buildPolicy
|
|
5605
|
+
};
|
|
5606
|
+
}
|
|
5594
5607
|
var Environment = class extends Session {
|
|
5595
5608
|
envData;
|
|
5596
5609
|
_apiKey;
|
|
@@ -5609,10 +5622,26 @@ var Environment = class extends Session {
|
|
|
5609
5622
|
get sandboxId() {
|
|
5610
5623
|
return this.envData.sandboxId;
|
|
5611
5624
|
}
|
|
5625
|
+
/** The ontology ID */
|
|
5626
|
+
get ontologyId() {
|
|
5627
|
+
return this.envData.ontologyId || this.envData.sandboxId;
|
|
5628
|
+
}
|
|
5612
5629
|
/** The subject ID */
|
|
5613
5630
|
get subjectId() {
|
|
5614
5631
|
return this.envData.subjectId;
|
|
5615
5632
|
}
|
|
5633
|
+
/** The named environment slot, such as dev or prod */
|
|
5634
|
+
get envName() {
|
|
5635
|
+
return this.envData.envName;
|
|
5636
|
+
}
|
|
5637
|
+
/** The named environment slot, such as dev or prod */
|
|
5638
|
+
get environment() {
|
|
5639
|
+
return this.envData.environment || this.envData.envName;
|
|
5640
|
+
}
|
|
5641
|
+
/** The resolved ontology version backing this environment */
|
|
5642
|
+
get versionId() {
|
|
5643
|
+
return this.envData.versionId || this.envData.buildId;
|
|
5644
|
+
}
|
|
5616
5645
|
/** Internal Granular user identifier for this environment */
|
|
5617
5646
|
get granularId() {
|
|
5618
5647
|
return this.envData.subjectId;
|
|
@@ -5696,7 +5725,8 @@ var Environment = class extends Session {
|
|
|
5696
5725
|
"Authorization": `Bearer ${this._apiKey}`
|
|
5697
5726
|
},
|
|
5698
5727
|
body: JSON.stringify({
|
|
5699
|
-
reason: "sdk_disconnect_http_fallback"
|
|
5728
|
+
reason: "sdk_disconnect_http_fallback",
|
|
5729
|
+
sessionId: this.client.currentSessionId
|
|
5700
5730
|
})
|
|
5701
5731
|
}
|
|
5702
5732
|
);
|
|
@@ -6480,7 +6510,7 @@ var Environment = class extends Session {
|
|
|
6480
6510
|
return super.unpublishAllEffects();
|
|
6481
6511
|
}
|
|
6482
6512
|
};
|
|
6483
|
-
var Granular = class {
|
|
6513
|
+
var Granular = class _Granular {
|
|
6484
6514
|
apiKey;
|
|
6485
6515
|
apiUrl;
|
|
6486
6516
|
httpUrl;
|
|
@@ -6584,7 +6614,7 @@ var Granular = class {
|
|
|
6584
6614
|
throw new Error("connect() requires either userId, granularId, or a user object returned by recordUser().");
|
|
6585
6615
|
}
|
|
6586
6616
|
/**
|
|
6587
|
-
* Connect to
|
|
6617
|
+
* Connect to an ontology environment and establish a real-time session.
|
|
6588
6618
|
*
|
|
6589
6619
|
* Effects are registered at the sandbox level via `granular.registerEffect()`
|
|
6590
6620
|
* or `granular.registerEffects()`. Sessions pick up live availability from
|
|
@@ -6596,7 +6626,8 @@ var Granular = class {
|
|
|
6596
6626
|
* @example
|
|
6597
6627
|
* ```typescript
|
|
6598
6628
|
* const environment = await granular.connect({
|
|
6599
|
-
*
|
|
6629
|
+
* ontology: 'my-ontology',
|
|
6630
|
+
* environment: 'dev',
|
|
6600
6631
|
* userId: 'user_123',
|
|
6601
6632
|
* permissions: ['agent'],
|
|
6602
6633
|
* });
|
|
@@ -6616,17 +6647,28 @@ var Granular = class {
|
|
|
6616
6647
|
*
|
|
6617
6648
|
* console.log(await job.result); // 'Hello!'
|
|
6618
6649
|
* ```
|
|
6619
|
-
|
|
6650
|
+
*/
|
|
6620
6651
|
async connect(options) {
|
|
6621
6652
|
const clientId = options.clientId || `client_${Date.now()}`;
|
|
6653
|
+
const ontology = options.ontology;
|
|
6654
|
+
if (!ontology) {
|
|
6655
|
+
throw new Error("connect() requires `ontology`.");
|
|
6656
|
+
}
|
|
6657
|
+
const environmentName = options.environment;
|
|
6658
|
+
if (!environmentName) {
|
|
6659
|
+
throw new Error("connect() requires `environment`.");
|
|
6660
|
+
}
|
|
6661
|
+
const tagName = options.tagName?.trim() || void 0;
|
|
6622
6662
|
const user = await this.resolveConnectUser(options);
|
|
6623
|
-
const sandbox = await this.findOrCreateSandbox(
|
|
6663
|
+
const sandbox = await this.findOrCreateSandbox(ontology);
|
|
6624
6664
|
for (const profileName of user.permissions) {
|
|
6625
6665
|
const profileId = await this.ensurePermissionProfile(sandbox.sandboxId, profileName);
|
|
6626
6666
|
await this.ensureAssignment(user.granularId, sandbox.sandboxId, profileId);
|
|
6627
6667
|
}
|
|
6628
6668
|
const envData = await this.environments.create(sandbox.sandboxId, {
|
|
6629
6669
|
subjectId: user.granularId,
|
|
6670
|
+
environment: environmentName,
|
|
6671
|
+
tagName,
|
|
6630
6672
|
permissionProfileId: null
|
|
6631
6673
|
});
|
|
6632
6674
|
await this.activateEnvironment(envData.environmentId);
|
|
@@ -6638,6 +6680,120 @@ var Granular = class {
|
|
|
6638
6680
|
initialHeap: options.initialHeap
|
|
6639
6681
|
})
|
|
6640
6682
|
});
|
|
6683
|
+
return this.bindWebSocketEnvironment(envData, clientId, session);
|
|
6684
|
+
}
|
|
6685
|
+
/**
|
|
6686
|
+
* List active (open) sessions for an environment — each session is one agent conversation thread.
|
|
6687
|
+
*/
|
|
6688
|
+
async listOpenSessions(filters) {
|
|
6689
|
+
return this.listSessionsForEnvironment(filters.environmentId, "active");
|
|
6690
|
+
}
|
|
6691
|
+
/**
|
|
6692
|
+
* List closed sessions for an environment (conversations that have disconnected).
|
|
6693
|
+
*/
|
|
6694
|
+
async listClosedSessions(filters) {
|
|
6695
|
+
return this.listSessionsForEnvironment(filters.environmentId, "closed");
|
|
6696
|
+
}
|
|
6697
|
+
async listSessionsForEnvironment(environmentId, status) {
|
|
6698
|
+
const query = new URLSearchParams({ environmentId, status });
|
|
6699
|
+
const res = await this.request(
|
|
6700
|
+
`/control/sessions?${query.toString()}`
|
|
6701
|
+
);
|
|
6702
|
+
const items = Array.isArray(res.items) ? res.items : [];
|
|
6703
|
+
return items.map((row) => this.normalizeConversationSession(row));
|
|
6704
|
+
}
|
|
6705
|
+
normalizeConversationSession(row) {
|
|
6706
|
+
const sessionId = String(row.sessionId ?? row.session_id ?? "");
|
|
6707
|
+
const environmentId = String(row.environmentId ?? row.environment_id ?? "");
|
|
6708
|
+
return {
|
|
6709
|
+
sessionId,
|
|
6710
|
+
tenantId: row.tenantId != null ? String(row.tenantId) : void 0,
|
|
6711
|
+
environmentId,
|
|
6712
|
+
versionId: row.versionId != null ? String(row.versionId) : null,
|
|
6713
|
+
docId: String(row.docId ?? row.doc_id ?? ""),
|
|
6714
|
+
status: row.status || "active",
|
|
6715
|
+
createdAt: _Granular.coerceIsoDate(row.createdAt ?? row.created_at),
|
|
6716
|
+
lastSeenAt: _Granular.coerceIsoDate(row.lastSeenAt ?? row.last_seen_at),
|
|
6717
|
+
summary: row.summary != null ? String(row.summary) : null,
|
|
6718
|
+
summaryUpdatedAt: row.summaryUpdatedAt != null || row.summary_updated_at != null ? _Granular.coerceIsoDate(row.summaryUpdatedAt ?? row.summary_updated_at) : null,
|
|
6719
|
+
subjectId: row.subjectId != null ? String(row.subjectId) : null,
|
|
6720
|
+
jobCount: typeof row.jobCount === "number" ? row.jobCount : void 0,
|
|
6721
|
+
toolCallCount: typeof row.toolCallCount === "number" ? row.toolCallCount : void 0
|
|
6722
|
+
};
|
|
6723
|
+
}
|
|
6724
|
+
static coerceIsoDate(value) {
|
|
6725
|
+
if (value instanceof Date) {
|
|
6726
|
+
return value.toISOString();
|
|
6727
|
+
}
|
|
6728
|
+
if (typeof value === "number") {
|
|
6729
|
+
return new Date(value).toISOString();
|
|
6730
|
+
}
|
|
6731
|
+
if (typeof value === "string") {
|
|
6732
|
+
return value;
|
|
6733
|
+
}
|
|
6734
|
+
return (/* @__PURE__ */ new Date(0)).toISOString();
|
|
6735
|
+
}
|
|
6736
|
+
/**
|
|
6737
|
+
* Create a new session (conversation) for an existing environment and connect to it.
|
|
6738
|
+
* The runtime graph is shared across all sessions for the same environment.
|
|
6739
|
+
*/
|
|
6740
|
+
async createSession(options) {
|
|
6741
|
+
const clientId = options.clientId || `client_${Date.now()}`;
|
|
6742
|
+
await this.activateEnvironment(options.environmentId);
|
|
6743
|
+
const envData = await this.environments.get(options.environmentId);
|
|
6744
|
+
const session = await this.request("/ws/sessions", {
|
|
6745
|
+
method: "POST",
|
|
6746
|
+
body: JSON.stringify({
|
|
6747
|
+
environmentId: options.environmentId,
|
|
6748
|
+
clientId,
|
|
6749
|
+
initialHeap: options.initialHeap
|
|
6750
|
+
})
|
|
6751
|
+
});
|
|
6752
|
+
return this.bindWebSocketEnvironment(envData, clientId, session);
|
|
6753
|
+
}
|
|
6754
|
+
/**
|
|
6755
|
+
* Connect to an existing open session (same conversation thread) using a freshly minted WebSocket token.
|
|
6756
|
+
*/
|
|
6757
|
+
async connectSession(options) {
|
|
6758
|
+
const clientId = options.clientId || `client_${Date.now()}`;
|
|
6759
|
+
const minted = await this.request(`/ws/sessions/${encodeURIComponent(options.sessionId)}/token`, {
|
|
6760
|
+
method: "POST",
|
|
6761
|
+
body: JSON.stringify({})
|
|
6762
|
+
});
|
|
6763
|
+
const envData = await this.environments.get(minted.environmentId);
|
|
6764
|
+
return this.bindWebSocketEnvironment(envData, clientId, minted);
|
|
6765
|
+
}
|
|
6766
|
+
/**
|
|
6767
|
+
* Mark a session closed in the control plane. If `environment` is the connected handle for that
|
|
6768
|
+
* `sessionId`, disconnects the WebSocket so the runtime tears down cleanly.
|
|
6769
|
+
*/
|
|
6770
|
+
async closeSession(sessionId, environment) {
|
|
6771
|
+
if (environment && environment.sessionId === sessionId) {
|
|
6772
|
+
await environment.disconnect();
|
|
6773
|
+
return;
|
|
6774
|
+
}
|
|
6775
|
+
await this.request(`/control/sessions/${encodeURIComponent(sessionId)}`, {
|
|
6776
|
+
method: "PATCH",
|
|
6777
|
+
body: JSON.stringify({
|
|
6778
|
+
status: "closed",
|
|
6779
|
+
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6780
|
+
})
|
|
6781
|
+
});
|
|
6782
|
+
}
|
|
6783
|
+
/**
|
|
6784
|
+
* Re-open a closed session in the index and connect to its existing runtime document.
|
|
6785
|
+
*/
|
|
6786
|
+
async reopenSession(sessionId, options) {
|
|
6787
|
+
await this.request(`/control/sessions/${encodeURIComponent(sessionId)}`, {
|
|
6788
|
+
method: "PATCH",
|
|
6789
|
+
body: JSON.stringify({
|
|
6790
|
+
status: "active",
|
|
6791
|
+
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6792
|
+
})
|
|
6793
|
+
});
|
|
6794
|
+
return this.connectSession({ sessionId, clientId: options?.clientId });
|
|
6795
|
+
}
|
|
6796
|
+
async bindWebSocketEnvironment(envData, clientId, session) {
|
|
6641
6797
|
const client = new WSClient({
|
|
6642
6798
|
url: session.wsUrl,
|
|
6643
6799
|
sessionId: session.sessionId,
|
|
@@ -7061,16 +7217,22 @@ var Granular = class {
|
|
|
7061
7217
|
const result = await this.request(
|
|
7062
7218
|
`/control/sandboxes/${sandboxId}/environments`
|
|
7063
7219
|
);
|
|
7064
|
-
return result.items;
|
|
7220
|
+
return result.items.map(normalizeEnvironmentData);
|
|
7065
7221
|
},
|
|
7066
7222
|
get: async (environmentId) => {
|
|
7067
|
-
return
|
|
7223
|
+
return normalizeEnvironmentData(
|
|
7224
|
+
await this.request(`/control/environments/${environmentId}`)
|
|
7225
|
+
);
|
|
7068
7226
|
},
|
|
7069
7227
|
create: async (sandboxId, data) => {
|
|
7070
|
-
|
|
7228
|
+
const environmentName = data.environment || data.envName;
|
|
7229
|
+
return normalizeEnvironmentData(await this.request(`/control/sandboxes/${sandboxId}/environments`, {
|
|
7071
7230
|
method: "POST",
|
|
7072
|
-
body: JSON.stringify(
|
|
7073
|
-
|
|
7231
|
+
body: JSON.stringify({
|
|
7232
|
+
...data,
|
|
7233
|
+
envName: environmentName
|
|
7234
|
+
})
|
|
7235
|
+
}));
|
|
7074
7236
|
},
|
|
7075
7237
|
delete: async (environmentId) => {
|
|
7076
7238
|
return this.request(`/control/environments/${environmentId}`, {
|