@granular-software/sdk 0.4.30 → 0.4.32
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 +25 -20
- package/dist/agent-evals.d.mts +7 -6
- package/dist/agent-evals.d.ts +7 -6
- package/dist/agent-evals.js +721 -286
- package/dist/agent-evals.js.map +1 -1
- package/dist/agent-evals.mjs +721 -286
- package/dist/agent-evals.mjs.map +1 -1
- package/dist/cli/index.js +537 -251
- package/dist/{client-BVvOMfln.d.mts → client-C2Gk641P.d.mts} +291 -163
- package/dist/{client-BVvOMfln.d.ts → client-C2Gk641P.d.ts} +291 -163
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +479 -196
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +478 -197
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4005,7 +4005,11 @@ var WSClient = class {
|
|
|
4005
4005
|
return null;
|
|
4006
4006
|
}
|
|
4007
4007
|
try {
|
|
4008
|
-
const
|
|
4008
|
+
const payloadSegment = parts[1];
|
|
4009
|
+
if (!payloadSegment) {
|
|
4010
|
+
return null;
|
|
4011
|
+
}
|
|
4012
|
+
const payloadRaw = this.decodeBase64Url(payloadSegment);
|
|
4009
4013
|
const payload = JSON.parse(payloadRaw);
|
|
4010
4014
|
if (typeof payload.exp !== "number" || !Number.isFinite(payload.exp)) {
|
|
4011
4015
|
return null;
|
|
@@ -4669,27 +4673,27 @@ var Session = class {
|
|
|
4669
4673
|
}
|
|
4670
4674
|
async publishTools(tools, revision = "1.0.0") {
|
|
4671
4675
|
throw new Error(
|
|
4672
|
-
"Environment-scoped effect publication was removed. Declare effects in the manifest and register live handlers with granular.
|
|
4676
|
+
"Environment-scoped effect publication was removed. Declare effects in the manifest and register live handlers with granular.ontology(environment.sandboxId).effects.registerMany(effects)."
|
|
4673
4677
|
);
|
|
4674
4678
|
}
|
|
4675
4679
|
async publishEffect(effect) {
|
|
4676
4680
|
throw new Error(
|
|
4677
|
-
"Environment-scoped effect publication was removed. Use granular.
|
|
4681
|
+
"Environment-scoped effect publication was removed. Use granular.ontology(environment.sandboxId).effects.register(effect)."
|
|
4678
4682
|
);
|
|
4679
4683
|
}
|
|
4680
4684
|
async publishEffects(effects) {
|
|
4681
4685
|
throw new Error(
|
|
4682
|
-
"Environment-scoped effect publication was removed. Use granular.
|
|
4686
|
+
"Environment-scoped effect publication was removed. Use granular.ontology(environment.sandboxId).effects.registerMany(effects)."
|
|
4683
4687
|
);
|
|
4684
4688
|
}
|
|
4685
4689
|
async unpublishEffect(name) {
|
|
4686
4690
|
throw new Error(
|
|
4687
|
-
"Environment-scoped effect publication was removed. Use granular.
|
|
4691
|
+
"Environment-scoped effect publication was removed. Use granular.ontology(environment.sandboxId).effects.unregister(effectName)."
|
|
4688
4692
|
);
|
|
4689
4693
|
}
|
|
4690
4694
|
async unpublishAllEffects() {
|
|
4691
4695
|
throw new Error(
|
|
4692
|
-
"Environment-scoped effect publication was removed. Use granular.
|
|
4696
|
+
"Environment-scoped effect publication was removed. Use granular.ontology(environment.sandboxId).effects.clear()."
|
|
4693
4697
|
);
|
|
4694
4698
|
}
|
|
4695
4699
|
/**
|
|
@@ -5082,6 +5086,7 @@ import { ${allImports} } from "./sandbox-tools";
|
|
|
5082
5086
|
this.eventListeners.set(event, []);
|
|
5083
5087
|
}
|
|
5084
5088
|
this.eventListeners.get(event).push(handler);
|
|
5089
|
+
return () => this.off(event, handler);
|
|
5085
5090
|
}
|
|
5086
5091
|
/**
|
|
5087
5092
|
* Unsubscribe from session events
|
|
@@ -5538,6 +5543,16 @@ var JobImplementation = class {
|
|
|
5538
5543
|
handler(message);
|
|
5539
5544
|
}
|
|
5540
5545
|
}
|
|
5546
|
+
return () => {
|
|
5547
|
+
const handlers = this.eventListeners.get(event);
|
|
5548
|
+
if (!handlers) {
|
|
5549
|
+
return;
|
|
5550
|
+
}
|
|
5551
|
+
this.eventListeners.set(
|
|
5552
|
+
event,
|
|
5553
|
+
handlers.filter((current) => current !== handler)
|
|
5554
|
+
);
|
|
5555
|
+
};
|
|
5541
5556
|
}
|
|
5542
5557
|
replayAgentMessage(message) {
|
|
5543
5558
|
this.captureAgentMessage(message);
|
|
@@ -11713,6 +11728,22 @@ function normalizeHeapSnapshot(raw) {
|
|
|
11713
11728
|
updatedAt: typeof heap.updatedAt === "number" ? heap.updatedAt : Date.now()
|
|
11714
11729
|
};
|
|
11715
11730
|
}
|
|
11731
|
+
function deriveRuntimeBaseUrl(apiEndpoint) {
|
|
11732
|
+
try {
|
|
11733
|
+
const endpoint = new URL(apiEndpoint);
|
|
11734
|
+
const graphqlSuffix = "/orchestrator/graphql";
|
|
11735
|
+
if (endpoint.pathname.endsWith(graphqlSuffix)) {
|
|
11736
|
+
endpoint.pathname = endpoint.pathname.slice(0, -graphqlSuffix.length);
|
|
11737
|
+
} else if (endpoint.pathname.endsWith("/graphql")) {
|
|
11738
|
+
endpoint.pathname = endpoint.pathname.slice(0, -"/graphql".length);
|
|
11739
|
+
}
|
|
11740
|
+
endpoint.search = "";
|
|
11741
|
+
endpoint.hash = "";
|
|
11742
|
+
return endpoint.toString().replace(/\/$/, "");
|
|
11743
|
+
} catch {
|
|
11744
|
+
return apiEndpoint.replace(/\/orchestrator\/graphql$/, "").replace(/\/$/, "");
|
|
11745
|
+
}
|
|
11746
|
+
}
|
|
11716
11747
|
function normalizeSubject(subject) {
|
|
11717
11748
|
const granularId = subject.granularId || subject.subjectId;
|
|
11718
11749
|
const userId = subject.userId || subject.identityId || granularId;
|
|
@@ -11752,12 +11783,13 @@ function normalizeEnvironmentData(environment) {
|
|
|
11752
11783
|
tracking: environment.tracking || buildPolicy
|
|
11753
11784
|
};
|
|
11754
11785
|
}
|
|
11755
|
-
var Environment = class
|
|
11786
|
+
var Environment = class {
|
|
11787
|
+
granular;
|
|
11756
11788
|
envData;
|
|
11757
11789
|
_apiKey;
|
|
11758
11790
|
_apiEndpoint;
|
|
11759
|
-
constructor(
|
|
11760
|
-
|
|
11791
|
+
constructor(granular, envData, apiKey, apiEndpoint) {
|
|
11792
|
+
this.granular = granular;
|
|
11761
11793
|
this.envData = envData;
|
|
11762
11794
|
this._apiKey = apiKey;
|
|
11763
11795
|
this._apiEndpoint = apiEndpoint;
|
|
@@ -11798,35 +11830,126 @@ var Environment = class extends Session {
|
|
|
11798
11830
|
get permissionProfileId() {
|
|
11799
11831
|
return this.envData.permissionProfileId;
|
|
11800
11832
|
}
|
|
11833
|
+
/** The current build policy backing this environment */
|
|
11834
|
+
get buildPolicy() {
|
|
11835
|
+
return this.envData.buildPolicy;
|
|
11836
|
+
}
|
|
11837
|
+
/** The current update state relative to the followed tag */
|
|
11838
|
+
get updateState() {
|
|
11839
|
+
return this.envData.updateState;
|
|
11840
|
+
}
|
|
11841
|
+
/** Convenience flag for whether this environment trails the current tag target */
|
|
11842
|
+
get isOutdated() {
|
|
11843
|
+
return this.envData.updateState === "update_available";
|
|
11844
|
+
}
|
|
11845
|
+
/** The followed tag name when this environment is tag-tracked */
|
|
11846
|
+
get tag() {
|
|
11847
|
+
return this.envData.tag?.name || this.envData.buildPolicy.tagName || null;
|
|
11848
|
+
}
|
|
11801
11849
|
/** The GraphQL API endpoint URL */
|
|
11802
11850
|
get apiEndpoint() {
|
|
11803
11851
|
return this._apiEndpoint;
|
|
11804
11852
|
}
|
|
11853
|
+
/** Internal auth token used for control-plane and runtime fallback requests */
|
|
11854
|
+
get authToken() {
|
|
11855
|
+
return this._apiKey;
|
|
11856
|
+
}
|
|
11857
|
+
/** Base runtime URL derived from the GraphQL endpoint */
|
|
11858
|
+
get runtimeBaseUrl() {
|
|
11859
|
+
return this.getRuntimeBaseUrl();
|
|
11860
|
+
}
|
|
11861
|
+
get sessions() {
|
|
11862
|
+
return {
|
|
11863
|
+
list: async (options) => this.listSessions(options?.status || "active"),
|
|
11864
|
+
create: async (options) => this.createSession(options),
|
|
11865
|
+
connect: async (sessionId, options) => this.connectSession(sessionId, options),
|
|
11866
|
+
reopen: async (sessionId, options) => this.reopenSession(sessionId, options),
|
|
11867
|
+
close: async (sessionId, session) => this.closeSession(sessionId, session)
|
|
11868
|
+
};
|
|
11869
|
+
}
|
|
11870
|
+
get data() {
|
|
11871
|
+
return {
|
|
11872
|
+
record: async (record) => this.recordObject(record),
|
|
11873
|
+
recordMany: async (records, options) => this.recordObjects(records, options),
|
|
11874
|
+
import: async (records, options) => this.enqueueRecordImport(records, options),
|
|
11875
|
+
listImports: async (status) => this.listRecordImports(status),
|
|
11876
|
+
getImport: async (importId) => this.getRecordImport(importId),
|
|
11877
|
+
getImportSummary: async () => this.getRecordImportSummary(),
|
|
11878
|
+
cancelImport: async (importId) => this.cancelRecordImport(importId),
|
|
11879
|
+
getAwaitingCount: async () => this.getAwaitingRecordCount()
|
|
11880
|
+
};
|
|
11881
|
+
}
|
|
11882
|
+
get feedback() {
|
|
11883
|
+
return {
|
|
11884
|
+
list: async () => this.listFeedback()
|
|
11885
|
+
};
|
|
11886
|
+
}
|
|
11805
11887
|
/**
|
|
11806
|
-
*
|
|
11807
|
-
*
|
|
11808
|
-
*
|
|
11809
|
-
*
|
|
11888
|
+
* Sessionless environments do not own a live transport, so disconnecting the
|
|
11889
|
+
* environment handle itself is a no-op. This keeps the public surface
|
|
11890
|
+
* symmetric with `EnvironmentSession.disconnect()` and lets callers always
|
|
11891
|
+
* clean up safely without tracking whether they currently hold an environment
|
|
11892
|
+
* or a session.
|
|
11810
11893
|
*/
|
|
11811
|
-
|
|
11812
|
-
const doc = this.document;
|
|
11813
|
-
return normalizeHeapSnapshot(doc?.heap);
|
|
11894
|
+
async disconnect() {
|
|
11814
11895
|
}
|
|
11815
|
-
|
|
11816
|
-
|
|
11817
|
-
const
|
|
11818
|
-
|
|
11819
|
-
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
|
|
11823
|
-
|
|
11824
|
-
|
|
11825
|
-
|
|
11826
|
-
|
|
11827
|
-
|
|
11828
|
-
|
|
11896
|
+
async listSessions(status = "active") {
|
|
11897
|
+
if (status === "all") {
|
|
11898
|
+
const [active, closed] = await Promise.all([
|
|
11899
|
+
this.granular.listOpenSessions({ environmentId: this.environmentId }),
|
|
11900
|
+
this.granular.listClosedSessions({ environmentId: this.environmentId })
|
|
11901
|
+
]);
|
|
11902
|
+
return [...active, ...closed].sort(
|
|
11903
|
+
(left, right) => Date.parse(right.lastSeenAt) - Date.parse(left.lastSeenAt)
|
|
11904
|
+
);
|
|
11905
|
+
}
|
|
11906
|
+
return status === "closed" ? this.granular.listClosedSessions({ environmentId: this.environmentId }) : this.granular.listOpenSessions({ environmentId: this.environmentId });
|
|
11907
|
+
}
|
|
11908
|
+
async createSession(options) {
|
|
11909
|
+
return this.granular.createSession({
|
|
11910
|
+
environmentId: this.environmentId,
|
|
11911
|
+
clientId: options?.clientId,
|
|
11912
|
+
initialHeap: options?.initialHeap
|
|
11913
|
+
});
|
|
11914
|
+
}
|
|
11915
|
+
async connectSession(sessionId, options) {
|
|
11916
|
+
const session = await this.granular["connectSession"]({
|
|
11917
|
+
sessionId,
|
|
11918
|
+
clientId: options?.clientId
|
|
11919
|
+
});
|
|
11920
|
+
if (session.environmentId !== this.environmentId) {
|
|
11921
|
+
await session.disconnect().catch(() => {
|
|
11922
|
+
session.disconnectTransport();
|
|
11923
|
+
});
|
|
11924
|
+
throw new Error(
|
|
11925
|
+
`Session ${sessionId} belongs to environment ${session.environmentId}, not ${this.environmentId}.`
|
|
11926
|
+
);
|
|
11927
|
+
}
|
|
11928
|
+
return session;
|
|
11929
|
+
}
|
|
11930
|
+
async reopenSession(sessionId, options) {
|
|
11931
|
+
const session = await this.granular.reopenSession(sessionId, {
|
|
11932
|
+
clientId: options?.clientId
|
|
11933
|
+
});
|
|
11934
|
+
if (session.environmentId !== this.environmentId) {
|
|
11935
|
+
await session.disconnect().catch(() => {
|
|
11936
|
+
session.disconnectTransport();
|
|
11937
|
+
});
|
|
11938
|
+
throw new Error(
|
|
11939
|
+
`Session ${sessionId} belongs to environment ${session.environmentId}, not ${this.environmentId}.`
|
|
11940
|
+
);
|
|
11829
11941
|
}
|
|
11942
|
+
return session;
|
|
11943
|
+
}
|
|
11944
|
+
async closeSession(sessionId, session) {
|
|
11945
|
+
await this.granular.closeSession(sessionId, session);
|
|
11946
|
+
}
|
|
11947
|
+
async listFeedback() {
|
|
11948
|
+
const response = await this.controlPlaneRequest(`/control/environments/${this.environmentId}/feedback`);
|
|
11949
|
+
return Array.isArray(response.items) ? response.items : [];
|
|
11950
|
+
}
|
|
11951
|
+
getRuntimeBaseUrl() {
|
|
11952
|
+
return deriveRuntimeBaseUrl(this._apiEndpoint);
|
|
11830
11953
|
}
|
|
11831
11954
|
async controlPlaneRequest(path, options = {}) {
|
|
11832
11955
|
const runtimeBase = this.getRuntimeBaseUrl();
|
|
@@ -11847,95 +11970,6 @@ var Environment = class extends Session {
|
|
|
11847
11970
|
}
|
|
11848
11971
|
return response.json();
|
|
11849
11972
|
}
|
|
11850
|
-
/**
|
|
11851
|
-
* Close the session and disconnect from the sandbox.
|
|
11852
|
-
*
|
|
11853
|
-
* Sends `client.goodbye` over WebSocket first, then issues an HTTP fallback
|
|
11854
|
-
* to the runtime goodbye endpoint if no definitive WS-side runtime notify
|
|
11855
|
-
* acknowledgement was observed.
|
|
11856
|
-
*/
|
|
11857
|
-
async disconnect() {
|
|
11858
|
-
let wsNotifiedRuntime = false;
|
|
11859
|
-
try {
|
|
11860
|
-
const goodbye = await this.rpc(
|
|
11861
|
-
"client.goodbye",
|
|
11862
|
-
{
|
|
11863
|
-
timestamp: Date.now()
|
|
11864
|
-
}
|
|
11865
|
-
);
|
|
11866
|
-
wsNotifiedRuntime = Boolean(goodbye?.ok && goodbye?.via);
|
|
11867
|
-
} catch {
|
|
11868
|
-
wsNotifiedRuntime = false;
|
|
11869
|
-
}
|
|
11870
|
-
if (!wsNotifiedRuntime) {
|
|
11871
|
-
try {
|
|
11872
|
-
const runtimeBase = this.getRuntimeBaseUrl();
|
|
11873
|
-
await fetch(
|
|
11874
|
-
`${runtimeBase}/orchestrator/runtime/environments/${this.environmentId}/session-goodbye`,
|
|
11875
|
-
{
|
|
11876
|
-
method: "POST",
|
|
11877
|
-
headers: {
|
|
11878
|
-
"Content-Type": "application/json",
|
|
11879
|
-
Authorization: `Bearer ${this._apiKey}`,
|
|
11880
|
-
Connection: "close"
|
|
11881
|
-
},
|
|
11882
|
-
body: JSON.stringify({
|
|
11883
|
-
reason: "sdk_disconnect_http_fallback",
|
|
11884
|
-
sessionId: this.client.currentSessionId
|
|
11885
|
-
})
|
|
11886
|
-
}
|
|
11887
|
-
);
|
|
11888
|
-
} catch {
|
|
11889
|
-
}
|
|
11890
|
-
}
|
|
11891
|
-
this.client.disconnect();
|
|
11892
|
-
}
|
|
11893
|
-
/**
|
|
11894
|
-
* Close only the socket transport without sending `client.goodbye`.
|
|
11895
|
-
*
|
|
11896
|
-
* Use this when the caller intends to immediately reattach to the same
|
|
11897
|
-
* session after an unexpected disconnect.
|
|
11898
|
-
*/
|
|
11899
|
-
disconnectTransport() {
|
|
11900
|
-
this.client.disconnect();
|
|
11901
|
-
}
|
|
11902
|
-
// ==================== GRAPH CONTAINER READINESS ====================
|
|
11903
|
-
/** The last known graph container status, updated by checkReadiness() or on heartbeat */
|
|
11904
|
-
graphContainerStatus = null;
|
|
11905
|
-
/**
|
|
11906
|
-
* Check if the graph container is ready and warm.
|
|
11907
|
-
*
|
|
11908
|
-
* Sends a lightweight heartbeat RPC to the Session DO which internally
|
|
11909
|
-
* pings the FalkorDB container. The response includes `graphContainerStatus`,
|
|
11910
|
-
* which is stored locally and emitted as a `readiness` event.
|
|
11911
|
-
*
|
|
11912
|
-
* Use this method to proactively warm the graph container before any
|
|
11913
|
-
* GraphQL query that requires it, or to poll the container's state in
|
|
11914
|
-
* the background.
|
|
11915
|
-
*
|
|
11916
|
-
* @returns The current graph container status object
|
|
11917
|
-
*
|
|
11918
|
-
* @example
|
|
11919
|
-
* ```typescript
|
|
11920
|
-
* const status = await env.checkReadiness();
|
|
11921
|
-
* console.log(status.status); // 'hot' | 'warming' | 'unknown'
|
|
11922
|
-
*
|
|
11923
|
-
* // Or listen for live updates
|
|
11924
|
-
* env.on('readiness', (status) => {
|
|
11925
|
-
* console.log('Graph is now:', status.status);
|
|
11926
|
-
* });
|
|
11927
|
-
* ```
|
|
11928
|
-
*/
|
|
11929
|
-
async checkReadiness() {
|
|
11930
|
-
const result = await this.client.call("client.heartbeat", {});
|
|
11931
|
-
const containerStatus = result?.graphContainerStatus ?? {
|
|
11932
|
-
lastKeepAliveAt: Date.now(),
|
|
11933
|
-
status: "unknown"
|
|
11934
|
-
};
|
|
11935
|
-
this.graphContainerStatus = containerStatus;
|
|
11936
|
-
this.emit("readiness", containerStatus);
|
|
11937
|
-
return containerStatus;
|
|
11938
|
-
}
|
|
11939
11973
|
// ==================== ID ↔ GRAPH PATH MAPPING ====================
|
|
11940
11974
|
/**
|
|
11941
11975
|
* Convert a class name + real-world ID into a unique graph path.
|
|
@@ -12065,7 +12099,9 @@ var Environment = class extends Session {
|
|
|
12065
12099
|
}
|
|
12066
12100
|
);
|
|
12067
12101
|
if (result.errors?.length) {
|
|
12068
|
-
throw new Error(
|
|
12102
|
+
throw new Error(
|
|
12103
|
+
`defineRelationship failed: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`
|
|
12104
|
+
);
|
|
12069
12105
|
}
|
|
12070
12106
|
return result.data.at.define_relationship;
|
|
12071
12107
|
}
|
|
@@ -12101,7 +12137,9 @@ var Environment = class extends Session {
|
|
|
12101
12137
|
{ path: modelPath }
|
|
12102
12138
|
);
|
|
12103
12139
|
if (result.errors?.length) {
|
|
12104
|
-
throw new Error(
|
|
12140
|
+
throw new Error(
|
|
12141
|
+
`getRelationships failed: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`
|
|
12142
|
+
);
|
|
12105
12143
|
}
|
|
12106
12144
|
return result.data?.model?.relationships || [];
|
|
12107
12145
|
}
|
|
@@ -12140,7 +12178,7 @@ var Environment = class extends Session {
|
|
|
12140
12178
|
{ target: targetPath }
|
|
12141
12179
|
);
|
|
12142
12180
|
if (result.errors?.length) {
|
|
12143
|
-
throw new Error(`attach failed: ${result.errors[0]
|
|
12181
|
+
throw new Error(`attach failed: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`);
|
|
12144
12182
|
}
|
|
12145
12183
|
}
|
|
12146
12184
|
/**
|
|
@@ -12175,7 +12213,7 @@ var Environment = class extends Session {
|
|
|
12175
12213
|
}`
|
|
12176
12214
|
);
|
|
12177
12215
|
if (result.errors?.length) {
|
|
12178
|
-
throw new Error(`detach failed: ${result.errors[0]
|
|
12216
|
+
throw new Error(`detach failed: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`);
|
|
12179
12217
|
}
|
|
12180
12218
|
}
|
|
12181
12219
|
/**
|
|
@@ -12202,7 +12240,9 @@ var Environment = class extends Session {
|
|
|
12202
12240
|
}`
|
|
12203
12241
|
);
|
|
12204
12242
|
if (result.errors?.length) {
|
|
12205
|
-
throw new Error(
|
|
12243
|
+
throw new Error(
|
|
12244
|
+
`listRelated failed: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`
|
|
12245
|
+
);
|
|
12206
12246
|
}
|
|
12207
12247
|
return result.data?.at?.at?.list_related || [];
|
|
12208
12248
|
}
|
|
@@ -12295,7 +12335,7 @@ var Environment = class extends Session {
|
|
|
12295
12335
|
async _runGraphql(query, label) {
|
|
12296
12336
|
const result = await this.graphql(query);
|
|
12297
12337
|
if (result.errors?.length) {
|
|
12298
|
-
throw new Error(`${label}: ${result.errors[0]
|
|
12338
|
+
throw new Error(`${label}: ${result.errors[0]?.message ?? "Unknown GraphQL error"}`);
|
|
12299
12339
|
}
|
|
12300
12340
|
return result.data;
|
|
12301
12341
|
}
|
|
@@ -12640,7 +12680,11 @@ var Environment = class extends Session {
|
|
|
12640
12680
|
*/
|
|
12641
12681
|
async recordObject(options) {
|
|
12642
12682
|
const results = await this.recordObjects([options]);
|
|
12643
|
-
|
|
12683
|
+
const result = results[0];
|
|
12684
|
+
if (!result) {
|
|
12685
|
+
throw new Error("recordObject: no result returned for record");
|
|
12686
|
+
}
|
|
12687
|
+
return result;
|
|
12644
12688
|
}
|
|
12645
12689
|
/**
|
|
12646
12690
|
* Batch version of `recordObject()`.
|
|
@@ -12692,7 +12736,13 @@ var Environment = class extends Session {
|
|
|
12692
12736
|
);
|
|
12693
12737
|
}
|
|
12694
12738
|
for (let index = 0; index < items.length; index += 1) {
|
|
12695
|
-
|
|
12739
|
+
const item = items[index];
|
|
12740
|
+
if (!item) {
|
|
12741
|
+
throw new Error(
|
|
12742
|
+
`recordObjects: chunk ${plan.chunkIndex + 1} returned an empty result at index ${index}`
|
|
12743
|
+
);
|
|
12744
|
+
}
|
|
12745
|
+
results[plan.offset + index] = item;
|
|
12696
12746
|
}
|
|
12697
12747
|
if (onChunk) {
|
|
12698
12748
|
const info = {
|
|
@@ -12796,36 +12846,186 @@ var Environment = class extends Session {
|
|
|
12796
12846
|
}
|
|
12797
12847
|
);
|
|
12798
12848
|
}
|
|
12799
|
-
|
|
12849
|
+
};
|
|
12850
|
+
var EnvironmentSession = class extends Session {
|
|
12851
|
+
environment;
|
|
12852
|
+
/** The last known graph container status, updated by checkReadiness() or on heartbeat */
|
|
12853
|
+
graphContainerStatus = null;
|
|
12854
|
+
constructor(client, environment, clientId) {
|
|
12855
|
+
super(client, clientId);
|
|
12856
|
+
this.environment = environment;
|
|
12857
|
+
}
|
|
12858
|
+
get environmentId() {
|
|
12859
|
+
return this.environment.environmentId;
|
|
12860
|
+
}
|
|
12861
|
+
get sandboxId() {
|
|
12862
|
+
return this.environment.sandboxId;
|
|
12863
|
+
}
|
|
12864
|
+
get ontologyId() {
|
|
12865
|
+
return this.environment.ontologyId;
|
|
12866
|
+
}
|
|
12867
|
+
get subjectId() {
|
|
12868
|
+
return this.environment.subjectId;
|
|
12869
|
+
}
|
|
12870
|
+
get envName() {
|
|
12871
|
+
return this.environment.envName;
|
|
12872
|
+
}
|
|
12873
|
+
get versionId() {
|
|
12874
|
+
return this.environment.versionId;
|
|
12875
|
+
}
|
|
12876
|
+
get granularId() {
|
|
12877
|
+
return this.environment.granularId;
|
|
12878
|
+
}
|
|
12879
|
+
get permissionProfileId() {
|
|
12880
|
+
return this.environment.permissionProfileId;
|
|
12881
|
+
}
|
|
12882
|
+
get apiEndpoint() {
|
|
12883
|
+
return this.environment.apiEndpoint;
|
|
12884
|
+
}
|
|
12885
|
+
get data() {
|
|
12886
|
+
return this.environment.data;
|
|
12887
|
+
}
|
|
12888
|
+
get feedback() {
|
|
12889
|
+
return this.environment.feedback;
|
|
12890
|
+
}
|
|
12800
12891
|
/**
|
|
12801
|
-
*
|
|
12892
|
+
* Return a plain JS snapshot of the synced session heap.
|
|
12802
12893
|
*/
|
|
12803
|
-
|
|
12804
|
-
|
|
12894
|
+
getHeap() {
|
|
12895
|
+
const doc = this.document;
|
|
12896
|
+
return normalizeHeapSnapshot(doc?.heap);
|
|
12897
|
+
}
|
|
12898
|
+
async graphql(query, variables) {
|
|
12899
|
+
return this.environment.graphql(query, variables);
|
|
12900
|
+
}
|
|
12901
|
+
async defineRelationship(options) {
|
|
12902
|
+
return this.environment.defineRelationship(options);
|
|
12903
|
+
}
|
|
12904
|
+
async getRelationships(modelPath) {
|
|
12905
|
+
return this.environment.getRelationships(modelPath);
|
|
12906
|
+
}
|
|
12907
|
+
async attach(modelPath, submodelPath, targetPath) {
|
|
12908
|
+
return this.environment.attach(modelPath, submodelPath, targetPath);
|
|
12909
|
+
}
|
|
12910
|
+
async detach(modelPath, submodelPath, targetPath) {
|
|
12911
|
+
return this.environment.detach(modelPath, submodelPath, targetPath);
|
|
12912
|
+
}
|
|
12913
|
+
async listRelated(modelPath, submodelPath) {
|
|
12914
|
+
return this.environment.listRelated(modelPath, submodelPath);
|
|
12915
|
+
}
|
|
12916
|
+
async applyManifest(manifest) {
|
|
12917
|
+
return this.environment.applyManifest(manifest);
|
|
12918
|
+
}
|
|
12919
|
+
async recordObject(options) {
|
|
12920
|
+
return this.environment.recordObject(options);
|
|
12921
|
+
}
|
|
12922
|
+
async recordObjects(records, options) {
|
|
12923
|
+
return this.environment.recordObjects(records, options);
|
|
12924
|
+
}
|
|
12925
|
+
async enqueueRecordImport(records, options = {}) {
|
|
12926
|
+
return this.environment.enqueueRecordImport(records, options);
|
|
12927
|
+
}
|
|
12928
|
+
async listRecordImports(status) {
|
|
12929
|
+
return this.environment.listRecordImports(status);
|
|
12930
|
+
}
|
|
12931
|
+
async getRecordImportSummary() {
|
|
12932
|
+
return this.environment.getRecordImportSummary();
|
|
12933
|
+
}
|
|
12934
|
+
async getAwaitingRecordCount() {
|
|
12935
|
+
return this.environment.getAwaitingRecordCount();
|
|
12936
|
+
}
|
|
12937
|
+
async getRecordImport(importId) {
|
|
12938
|
+
return this.environment.getRecordImport(importId);
|
|
12939
|
+
}
|
|
12940
|
+
async cancelRecordImport(importId) {
|
|
12941
|
+
return this.environment.cancelRecordImport(importId);
|
|
12942
|
+
}
|
|
12943
|
+
async listFeedback() {
|
|
12944
|
+
return this.environment.listFeedback();
|
|
12805
12945
|
}
|
|
12806
12946
|
/**
|
|
12807
|
-
*
|
|
12947
|
+
* Close the session and disconnect from the sandbox.
|
|
12948
|
+
*
|
|
12949
|
+
* Sends `client.goodbye` over WebSocket first, then issues an HTTP fallback
|
|
12950
|
+
* to the runtime goodbye endpoint if no definitive WS-side runtime notify
|
|
12951
|
+
* acknowledgement was observed.
|
|
12808
12952
|
*/
|
|
12809
|
-
async
|
|
12810
|
-
|
|
12953
|
+
async disconnect() {
|
|
12954
|
+
let wsNotifiedRuntime = false;
|
|
12955
|
+
try {
|
|
12956
|
+
const goodbye = await this.rpc(
|
|
12957
|
+
"client.goodbye",
|
|
12958
|
+
{
|
|
12959
|
+
timestamp: Date.now()
|
|
12960
|
+
}
|
|
12961
|
+
);
|
|
12962
|
+
wsNotifiedRuntime = Boolean(goodbye?.ok && goodbye?.via);
|
|
12963
|
+
} catch {
|
|
12964
|
+
wsNotifiedRuntime = false;
|
|
12965
|
+
}
|
|
12966
|
+
if (!wsNotifiedRuntime) {
|
|
12967
|
+
try {
|
|
12968
|
+
await fetch(
|
|
12969
|
+
`${this.environment.runtimeBaseUrl}/orchestrator/runtime/environments/${this.environmentId}/session-goodbye`,
|
|
12970
|
+
{
|
|
12971
|
+
method: "POST",
|
|
12972
|
+
headers: {
|
|
12973
|
+
"Content-Type": "application/json",
|
|
12974
|
+
Authorization: `Bearer ${this.environment.authToken}`,
|
|
12975
|
+
Connection: "close"
|
|
12976
|
+
},
|
|
12977
|
+
body: JSON.stringify({
|
|
12978
|
+
reason: "sdk_disconnect_http_fallback",
|
|
12979
|
+
sessionId: this.client.currentSessionId
|
|
12980
|
+
})
|
|
12981
|
+
}
|
|
12982
|
+
);
|
|
12983
|
+
} catch {
|
|
12984
|
+
}
|
|
12985
|
+
}
|
|
12986
|
+
this.client.disconnect();
|
|
12811
12987
|
}
|
|
12812
12988
|
/**
|
|
12813
|
-
*
|
|
12989
|
+
* Close only the socket transport without sending `client.goodbye`.
|
|
12814
12990
|
*/
|
|
12815
|
-
|
|
12816
|
-
|
|
12991
|
+
disconnectTransport() {
|
|
12992
|
+
this.client.disconnect();
|
|
12817
12993
|
}
|
|
12818
12994
|
/**
|
|
12819
|
-
*
|
|
12995
|
+
* Backwards-compatible alias for `disconnect()`.
|
|
12820
12996
|
*/
|
|
12821
|
-
async
|
|
12822
|
-
|
|
12997
|
+
async close() {
|
|
12998
|
+
await this.disconnect();
|
|
12823
12999
|
}
|
|
12824
13000
|
/**
|
|
12825
|
-
*
|
|
13001
|
+
* Check if the graph container is ready and warm.
|
|
12826
13002
|
*/
|
|
12827
|
-
async
|
|
12828
|
-
|
|
13003
|
+
async checkReadiness() {
|
|
13004
|
+
const result = await this.client.call("client.heartbeat", {});
|
|
13005
|
+
const containerStatus = result?.graphContainerStatus ?? {
|
|
13006
|
+
lastKeepAliveAt: Date.now(),
|
|
13007
|
+
status: "unknown"
|
|
13008
|
+
};
|
|
13009
|
+
this.graphContainerStatus = containerStatus;
|
|
13010
|
+
this.emit("readiness", containerStatus);
|
|
13011
|
+
return containerStatus;
|
|
13012
|
+
}
|
|
13013
|
+
};
|
|
13014
|
+
var OntologyHandle = class {
|
|
13015
|
+
granular;
|
|
13016
|
+
ontologyNameOrId;
|
|
13017
|
+
constructor(granular, ontologyNameOrId) {
|
|
13018
|
+
this.granular = granular;
|
|
13019
|
+
this.ontologyNameOrId = ontologyNameOrId;
|
|
13020
|
+
}
|
|
13021
|
+
get effects() {
|
|
13022
|
+
return {
|
|
13023
|
+
register: async (effect) => this.granular.registerEffect(this.ontologyNameOrId, effect),
|
|
13024
|
+
registerMany: async (effects) => this.granular.registerEffects(this.ontologyNameOrId, effects),
|
|
13025
|
+
unregister: async (name) => this.granular.unregisterEffect(this.ontologyNameOrId, name),
|
|
13026
|
+
clear: async () => this.granular.unregisterAllEffects(this.ontologyNameOrId),
|
|
13027
|
+
disconnect: async () => this.granular.disconnectEffects(this.ontologyNameOrId)
|
|
13028
|
+
};
|
|
12829
13029
|
}
|
|
12830
13030
|
};
|
|
12831
13031
|
var Granular = class _Granular {
|
|
@@ -12862,6 +13062,12 @@ var Granular = class _Granular {
|
|
|
12862
13062
|
this.onReconnectError = options.onReconnectError;
|
|
12863
13063
|
this.httpUrl = this.apiUrl.replace(/^wss:\/\//, "https://").replace(/^ws:\/\//, "http://").replace(/\/ws$/, "");
|
|
12864
13064
|
}
|
|
13065
|
+
/**
|
|
13066
|
+
* Return an ontology-scoped handle for effects and other ontology-level APIs.
|
|
13067
|
+
*/
|
|
13068
|
+
ontology(ontologyNameOrId) {
|
|
13069
|
+
return new OntologyHandle(this, ontologyNameOrId);
|
|
13070
|
+
}
|
|
12865
13071
|
/**
|
|
12866
13072
|
* Records/upserts a user and prepares them for sandbox connections
|
|
12867
13073
|
*
|
|
@@ -12898,7 +13104,23 @@ var Granular = class _Granular {
|
|
|
12898
13104
|
permissions: options.permissions || []
|
|
12899
13105
|
});
|
|
12900
13106
|
}
|
|
13107
|
+
/**
|
|
13108
|
+
* Alias for `recordUser()` with user-facing naming that matches upsert semantics.
|
|
13109
|
+
*/
|
|
13110
|
+
async upsertUser(options) {
|
|
13111
|
+
return this.recordUser(options);
|
|
13112
|
+
}
|
|
12901
13113
|
async resolveConnectUser(options) {
|
|
13114
|
+
const providedIdentityCount = [
|
|
13115
|
+
Boolean(options.user),
|
|
13116
|
+
Boolean(options.userId),
|
|
13117
|
+
Boolean(options.granularId)
|
|
13118
|
+
].filter(Boolean).length;
|
|
13119
|
+
if (providedIdentityCount !== 1) {
|
|
13120
|
+
throw new Error(
|
|
13121
|
+
"openEnvironment() requires exactly one of userId, granularId, or a user object returned by recordUser()."
|
|
13122
|
+
);
|
|
13123
|
+
}
|
|
12902
13124
|
if (options.user) {
|
|
12903
13125
|
const user = normalizeUser(options.user);
|
|
12904
13126
|
return {
|
|
@@ -12935,56 +13157,85 @@ var Granular = class _Granular {
|
|
|
12935
13157
|
};
|
|
12936
13158
|
}
|
|
12937
13159
|
throw new Error(
|
|
12938
|
-
"
|
|
13160
|
+
"openEnvironment() requires either userId, granularId, or a user object returned by recordUser()."
|
|
12939
13161
|
);
|
|
12940
13162
|
}
|
|
12941
13163
|
/**
|
|
12942
|
-
*
|
|
12943
|
-
*
|
|
12944
|
-
* Effects are registered at the sandbox level via `granular.registerEffect()`
|
|
12945
|
-
* or `granular.registerEffects()`. Sessions pick up live availability from
|
|
12946
|
-
* the sandbox registry automatically.
|
|
12947
|
-
*
|
|
12948
|
-
* @param options - Connection options
|
|
12949
|
-
* @returns An active environment session
|
|
13164
|
+
* Open or resolve an ontology environment for one user without opening a session.
|
|
12950
13165
|
*
|
|
12951
13166
|
* @example
|
|
12952
13167
|
* ```typescript
|
|
12953
|
-
* const environment = await granular.
|
|
13168
|
+
* const environment = await granular.openEnvironment({
|
|
12954
13169
|
* ontology: 'my-ontology',
|
|
12955
|
-
*
|
|
13170
|
+
* tag: 'dev',
|
|
12956
13171
|
* userId: 'user_123',
|
|
12957
13172
|
* permissions: ['agent'],
|
|
12958
13173
|
* });
|
|
12959
13174
|
*
|
|
12960
|
-
* await
|
|
12961
|
-
*
|
|
12962
|
-
*
|
|
12963
|
-
*
|
|
12964
|
-
* handler: async () => 'Hello!',
|
|
13175
|
+
* await environment.data.record({
|
|
13176
|
+
* className: 'customer',
|
|
13177
|
+
* id: 'acme',
|
|
13178
|
+
* fields: { name: 'Acme' },
|
|
12965
13179
|
* });
|
|
12966
13180
|
*
|
|
12967
|
-
*
|
|
12968
|
-
* const job = await
|
|
12969
|
-
*
|
|
12970
|
-
* return await tools.greet({});
|
|
12971
|
-
* `);
|
|
12972
|
-
*
|
|
12973
|
-
* console.log(await job.result); // 'Hello!'
|
|
13181
|
+
* const session = await environment.sessions.create();
|
|
13182
|
+
* const job = await session.submitJob(`return "hello";`);
|
|
13183
|
+
* console.log(await job.result);
|
|
12974
13184
|
* ```
|
|
12975
13185
|
*/
|
|
13186
|
+
async openEnvironment(options) {
|
|
13187
|
+
const envData = await this.resolveOpenEnvironmentData(
|
|
13188
|
+
options,
|
|
13189
|
+
"openEnvironment"
|
|
13190
|
+
);
|
|
13191
|
+
return this.bindEnvironmentHandle(envData);
|
|
13192
|
+
}
|
|
13193
|
+
/**
|
|
13194
|
+
* Deprecated compatibility alias for `openEnvironment()`.
|
|
13195
|
+
*
|
|
13196
|
+
* `connect()` no longer opens a runtime session automatically.
|
|
13197
|
+
*/
|
|
12976
13198
|
async connect(options) {
|
|
12977
|
-
|
|
13199
|
+
return this.openEnvironment({
|
|
13200
|
+
...options,
|
|
13201
|
+
tag: this.resolveRequestedTag(options, "connect"),
|
|
13202
|
+
permissions: options.permissions || options.user?.permissions || []
|
|
13203
|
+
});
|
|
13204
|
+
}
|
|
13205
|
+
resolveRequestedTag(options, methodName) {
|
|
13206
|
+
const tag = options.tag?.trim() || options.tagName?.trim() || options.environment?.trim();
|
|
13207
|
+
if (!tag) {
|
|
13208
|
+
throw new Error(`${methodName}() requires \`tag\`.`);
|
|
13209
|
+
}
|
|
13210
|
+
return tag;
|
|
13211
|
+
}
|
|
13212
|
+
buildManagedEnvironmentName(tag, versionId) {
|
|
13213
|
+
return `__sdk__${tag}__${versionId}`;
|
|
13214
|
+
}
|
|
13215
|
+
matchesTagTrackedEnvironment(environment, tagName, tagId) {
|
|
13216
|
+
const environmentTagName = environment.tag?.name || environment.buildPolicy.tagName || null;
|
|
13217
|
+
return environment.tagId === tagId || environmentTagName === tagName || environment.environment === tagName || environment.envName === tagName || environment.environment === this.buildManagedEnvironmentName(tagName, environment.versionId) || environment.envName === this.buildManagedEnvironmentName(tagName, environment.versionId);
|
|
13218
|
+
}
|
|
13219
|
+
sortEnvironmentsByRecency(environments) {
|
|
13220
|
+
return [...environments].sort(
|
|
13221
|
+
(left, right) => right.updatedAt - left.updatedAt
|
|
13222
|
+
);
|
|
13223
|
+
}
|
|
13224
|
+
async resolveOpenEnvironmentData(options, methodName) {
|
|
12978
13225
|
const ontology = options.ontology;
|
|
12979
13226
|
if (!ontology) {
|
|
12980
|
-
throw new Error(
|
|
13227
|
+
throw new Error(`${methodName}() requires \`ontology\`.`);
|
|
12981
13228
|
}
|
|
12982
|
-
const
|
|
12983
|
-
if (!
|
|
12984
|
-
throw new Error(
|
|
13229
|
+
const tagName = options.tag?.trim();
|
|
13230
|
+
if (!tagName) {
|
|
13231
|
+
throw new Error(`${methodName}() requires \`tag\`.`);
|
|
12985
13232
|
}
|
|
12986
|
-
const tagName = options.tagName?.trim() || void 0;
|
|
12987
13233
|
const user = await this.resolveConnectUser(options);
|
|
13234
|
+
if (!Array.isArray(user.permissions) || user.permissions.length === 0) {
|
|
13235
|
+
throw new Error(
|
|
13236
|
+
`${methodName}() requires at least one permission so the SDK can ensure assignments for new users.`
|
|
13237
|
+
);
|
|
13238
|
+
}
|
|
12988
13239
|
const sandbox = await this.findOrCreateSandbox(ontology);
|
|
12989
13240
|
for (const profileName of user.permissions) {
|
|
12990
13241
|
const profileId = await this.ensurePermissionProfile(
|
|
@@ -12997,22 +13248,49 @@ var Granular = class _Granular {
|
|
|
12997
13248
|
profileId
|
|
12998
13249
|
);
|
|
12999
13250
|
}
|
|
13000
|
-
const
|
|
13251
|
+
const tags = await this.request(
|
|
13252
|
+
`/control/sandboxes/${sandbox.sandboxId}/tags`
|
|
13253
|
+
);
|
|
13254
|
+
const tag = (tags.items || []).find(
|
|
13255
|
+
(candidate) => Boolean(candidate?.name === tagName)
|
|
13256
|
+
);
|
|
13257
|
+
if (!tag) {
|
|
13258
|
+
throw new Error(
|
|
13259
|
+
`Tag "${tagName}" was not found for ontology ${sandbox.sandboxId}.`
|
|
13260
|
+
);
|
|
13261
|
+
}
|
|
13262
|
+
const targetVersionId = tag.targetVersionId || tag.targetBuildId;
|
|
13263
|
+
if (!targetVersionId) {
|
|
13264
|
+
throw new Error(
|
|
13265
|
+
`Tag "${tagName}" does not currently point to a build/version.`
|
|
13266
|
+
);
|
|
13267
|
+
}
|
|
13268
|
+
const allEnvironments = await this.environments.list(sandbox.sandboxId);
|
|
13269
|
+
const userEnvironments = allEnvironments.filter(
|
|
13270
|
+
(environment) => environment.subjectId === user.granularId
|
|
13271
|
+
);
|
|
13272
|
+
const currentMatches = this.sortEnvironmentsByRecency(
|
|
13273
|
+
userEnvironments.filter(
|
|
13274
|
+
(environment) => this.matchesTagTrackedEnvironment(environment, tagName, tag.tagId) && environment.versionId === targetVersionId
|
|
13275
|
+
)
|
|
13276
|
+
);
|
|
13277
|
+
if (currentMatches.length > 0) {
|
|
13278
|
+
return currentMatches[0];
|
|
13279
|
+
}
|
|
13280
|
+
const outdatedMatches = this.sortEnvironmentsByRecency(
|
|
13281
|
+
userEnvironments.filter(
|
|
13282
|
+
(environment) => this.matchesTagTrackedEnvironment(environment, tagName, tag.tagId)
|
|
13283
|
+
)
|
|
13284
|
+
);
|
|
13285
|
+
if (outdatedMatches.length > 0 && options.createFreshIfOutdated !== true) {
|
|
13286
|
+
return outdatedMatches[0];
|
|
13287
|
+
}
|
|
13288
|
+
return this.environments.create(sandbox.sandboxId, {
|
|
13001
13289
|
subjectId: user.granularId,
|
|
13002
|
-
environment:
|
|
13003
|
-
|
|
13290
|
+
environment: this.buildManagedEnvironmentName(tagName, targetVersionId),
|
|
13291
|
+
tagId: tag.tagId,
|
|
13004
13292
|
permissionProfileId: null
|
|
13005
13293
|
});
|
|
13006
|
-
await this.activateEnvironment(envData.environmentId);
|
|
13007
|
-
const session = await this.request("/ws/sessions", {
|
|
13008
|
-
method: "POST",
|
|
13009
|
-
body: JSON.stringify({
|
|
13010
|
-
environmentId: envData.environmentId,
|
|
13011
|
-
clientId,
|
|
13012
|
-
initialHeap: options.initialHeap
|
|
13013
|
-
})
|
|
13014
|
-
});
|
|
13015
|
-
return this.bindWebSocketEnvironment(envData, clientId, session);
|
|
13016
13294
|
}
|
|
13017
13295
|
/**
|
|
13018
13296
|
* List active (open) sessions for an environment — each session is one agent conversation thread.
|
|
@@ -13075,6 +13353,7 @@ var Granular = class _Granular {
|
|
|
13075
13353
|
const clientId = options.clientId || `client_${Date.now()}`;
|
|
13076
13354
|
await this.activateEnvironment(options.environmentId);
|
|
13077
13355
|
const envData = await this.environments.get(options.environmentId);
|
|
13356
|
+
const environment = this.bindEnvironmentHandle(envData);
|
|
13078
13357
|
const session = await this.request("/ws/sessions", {
|
|
13079
13358
|
method: "POST",
|
|
13080
13359
|
body: JSON.stringify({
|
|
@@ -13083,7 +13362,7 @@ var Granular = class _Granular {
|
|
|
13083
13362
|
initialHeap: options.initialHeap
|
|
13084
13363
|
})
|
|
13085
13364
|
});
|
|
13086
|
-
return this.
|
|
13365
|
+
return this.bindWebSocketEnvironmentSession(environment, clientId, session);
|
|
13087
13366
|
}
|
|
13088
13367
|
/**
|
|
13089
13368
|
* Connect to an existing open session (same conversation thread) using a freshly minted WebSocket token.
|
|
@@ -13095,7 +13374,8 @@ var Granular = class _Granular {
|
|
|
13095
13374
|
body: JSON.stringify({})
|
|
13096
13375
|
});
|
|
13097
13376
|
const envData = await this.environments.get(minted.environmentId);
|
|
13098
|
-
|
|
13377
|
+
const environment = this.bindEnvironmentHandle(envData);
|
|
13378
|
+
return this.bindWebSocketEnvironmentSession(environment, clientId, minted);
|
|
13099
13379
|
}
|
|
13100
13380
|
/**
|
|
13101
13381
|
* Mark a session closed in the control plane. If `environment` is the connected handle for that
|
|
@@ -13127,7 +13407,11 @@ var Granular = class _Granular {
|
|
|
13127
13407
|
});
|
|
13128
13408
|
return this.connectSession({ sessionId, clientId: options?.clientId });
|
|
13129
13409
|
}
|
|
13130
|
-
|
|
13410
|
+
bindEnvironmentHandle(envData) {
|
|
13411
|
+
const graphqlEndpoint = `${this.httpUrl}/orchestrator/graphql`;
|
|
13412
|
+
return new Environment(this, envData, this.apiKey, graphqlEndpoint);
|
|
13413
|
+
}
|
|
13414
|
+
async bindWebSocketEnvironmentSession(environment, clientId, session) {
|
|
13131
13415
|
const client = new WSClient({
|
|
13132
13416
|
url: session.wsUrl,
|
|
13133
13417
|
sessionId: session.sessionId,
|
|
@@ -13138,16 +13422,13 @@ var Granular = class _Granular {
|
|
|
13138
13422
|
onReconnectError: this.onReconnectError
|
|
13139
13423
|
});
|
|
13140
13424
|
await client.connect();
|
|
13141
|
-
const
|
|
13142
|
-
const environment = new Environment(
|
|
13425
|
+
const environmentSession = new EnvironmentSession(
|
|
13143
13426
|
client,
|
|
13144
|
-
|
|
13145
|
-
clientId
|
|
13146
|
-
this.apiKey,
|
|
13147
|
-
graphqlEndpoint
|
|
13427
|
+
environment,
|
|
13428
|
+
clientId
|
|
13148
13429
|
);
|
|
13149
|
-
await
|
|
13150
|
-
return
|
|
13430
|
+
await environmentSession.hello();
|
|
13431
|
+
return environmentSession;
|
|
13151
13432
|
}
|
|
13152
13433
|
async activateEnvironment(environmentId) {
|
|
13153
13434
|
await this.request(`/orchestrator/runtime/environments/${environmentId}/activate`, {
|
|
@@ -15539,7 +15820,9 @@ function buildSessionTranscript(input) {
|
|
|
15539
15820
|
}
|
|
15540
15821
|
|
|
15541
15822
|
exports.Environment = Environment;
|
|
15823
|
+
exports.EnvironmentSession = EnvironmentSession;
|
|
15542
15824
|
exports.Granular = Granular;
|
|
15825
|
+
exports.OntologyHandle = OntologyHandle;
|
|
15543
15826
|
exports.Session = Session;
|
|
15544
15827
|
exports.WSClient = WSClient;
|
|
15545
15828
|
exports.buildContinuationInstruction = buildContinuationInstruction;
|