@granular-software/sdk 0.4.16 → 0.4.17

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/dist/index.d.mts CHANGED
@@ -359,7 +359,7 @@ interface BuildListResponse {
359
359
  }
360
360
  interface SemanticVersionDiffEntry {
361
361
  operationId: string;
362
- kind: 'create' | 'update' | 'relationship' | 'effect' | 'unknown';
362
+ kind: 'create' | 'update' | 'relationship' | 'effect' | 'eventStream' | 'unknown';
363
363
  changeType: 'added' | 'removed' | 'changed';
364
364
  label: string;
365
365
  additive: boolean;
@@ -1024,6 +1024,22 @@ interface ManifestEffectDeclaration {
1024
1024
  tags?: string[];
1025
1025
  metamodels?: ManifestEffectMetamodelSpec;
1026
1026
  }
1027
+ /**
1028
+ * An event type within an event stream definition
1029
+ */
1030
+ interface ManifestEventTypeDef {
1031
+ name: string;
1032
+ description?: string;
1033
+ payloadSchema: ManifestEffectSchema;
1034
+ }
1035
+ /**
1036
+ * Event stream definition for outgoing typed events
1037
+ */
1038
+ interface ManifestEventStreamDef {
1039
+ name: string;
1040
+ description?: string;
1041
+ eventTypes: ManifestEventTypeDef[];
1042
+ }
1027
1043
  /**
1028
1044
  * A single operation in a manifest volume
1029
1045
  */
@@ -1046,6 +1062,8 @@ interface ManifestOperation {
1046
1062
  defineRelationship?: ManifestRelationshipDef;
1047
1063
  /** Declare a build-owned effect */
1048
1064
  withEffect?: ManifestEffectDeclaration;
1065
+ /** Define an outgoing event stream with typed events */
1066
+ defineEventStream?: ManifestEventStreamDef;
1049
1067
  }
1050
1068
  /**
1051
1069
  * A volume in a manifest
@@ -1098,6 +1116,29 @@ interface APIError {
1098
1116
  interface DeleteResponse {
1099
1117
  deleted: boolean;
1100
1118
  }
1119
+ interface StreamEvent {
1120
+ eventId: string;
1121
+ streamName: string;
1122
+ eventType: string;
1123
+ payload: Record<string, unknown>;
1124
+ environmentId: string;
1125
+ sessionId?: string;
1126
+ subjectId?: string;
1127
+ source: 'sandbox' | 'api';
1128
+ isAcked: boolean;
1129
+ createdAt: number;
1130
+ }
1131
+ interface StreamSubscription {
1132
+ unsubscribe(): void;
1133
+ }
1134
+ interface StreamStats {
1135
+ streamName: string;
1136
+ eventType: string;
1137
+ total: number;
1138
+ last1h: number;
1139
+ last24h: number;
1140
+ unacked: number;
1141
+ }
1101
1142
 
1102
1143
  declare class WSClient {
1103
1144
  private ws;
@@ -1593,6 +1634,8 @@ declare class Environment extends Session {
1593
1634
  private _ensureWorkspaceToolsRoot;
1594
1635
  private _storeEffectSchemas;
1595
1636
  private _applyEffectMetamodels;
1637
+ private _ensureWorkspaceStreamsRoot;
1638
+ private _applyEventStreamDeclaration;
1596
1639
  private _applyEffectDeclaration;
1597
1640
  /**
1598
1641
  * Apply a single manifest operation via GraphQL
@@ -1887,6 +1930,40 @@ declare class Granular {
1887
1930
  create: (sandboxId: string, data: CreateEnvironmentData) => Promise<EnvironmentData>;
1888
1931
  delete: (environmentId: string) => Promise<DeleteResponse>;
1889
1932
  };
1933
+ /**
1934
+ * Event stream operations: query, subscribe, and acknowledge stream events
1935
+ */
1936
+ get streams(): {
1937
+ getEvents: (params: {
1938
+ ontology: string;
1939
+ stream: string;
1940
+ environment?: string;
1941
+ session?: string;
1942
+ eventTypes?: string[];
1943
+ since?: Date;
1944
+ until?: Date;
1945
+ isAcked?: boolean;
1946
+ limit?: number;
1947
+ offset?: number;
1948
+ }) => Promise<StreamEvent[]>;
1949
+ subscribe: (params: {
1950
+ ontology: string;
1951
+ stream: string;
1952
+ environment?: string;
1953
+ session?: string;
1954
+ eventTypes?: string[];
1955
+ since?: Date;
1956
+ onEvent: (event: StreamEvent) => void;
1957
+ onError?: (err: Error) => void;
1958
+ pollIntervalMs?: number;
1959
+ }) => StreamSubscription;
1960
+ ack: (eventId: string) => Promise<void>;
1961
+ ackBatch: (eventIds: string[]) => Promise<void>;
1962
+ getStats: (params: {
1963
+ ontology: string;
1964
+ environment?: string;
1965
+ }) => Promise<StreamStats[]>;
1966
+ };
1890
1967
  /**
1891
1968
  * Subject management
1892
1969
  */
@@ -1905,6 +1982,7 @@ declare class Granular {
1905
1982
  }) => Promise<Subject>;
1906
1983
  get: (id: string) => Promise<Subject>;
1907
1984
  };
1985
+ private _resolveSandboxId;
1908
1986
  /**
1909
1987
  * Make an authenticated API request
1910
1988
  */
@@ -1920,4 +1998,4 @@ type EffectRuntimeRequest = {
1920
1998
  declare function normalizeEffectBehaviors(value?: ManifestEffectMetamodelSpec | ResolvedEffectBehaviors | null): ResolvedEffectBehaviors;
1921
1999
  declare function invokeRegisteredEffect(effectMap: Map<string, ToolWithHandler>, request: EffectRuntimeRequest): Promise<unknown>;
1922
2000
 
1923
- export { type APIError, type AccessTokenProvider, type Assignment, type AssignmentListResponse, type Build, type BuildListResponse, type BuildPolicy, type BuildStatus, type ConnectOptions, type ConversationSessionInfo, type CreateEnvironmentData, type CreatePermissionProfileData, type CreateSandboxData, type DefineRelationshipOptions, type DeleteResponse, type DomainState, type EffectHandler, type EffectHandlerContext, type EffectInfo, type EffectInvocationMetadata, type EffectInvocationMode, type EffectSchema, type EffectWithHandler, type EffectsChangedEvent, type EndpointMode, Environment, type EnvironmentData, type EnvironmentListResponse, type EnvironmentRecordImportSummary, Granular, type GranularAuth, type GranularOptions, type GraphQLResult, type InstanceEffectHandler, type InstanceToolHandler, type Job, type JobFeedbackInput, type JobFeedbackMetadata, type JobFeedbackRecord, type JobFeedbackSentiment, type JobFeedbackToolCall, type JobStatus, type JobSubmitResult, type Manifest, type ManifestApprovalRequiredSpec, type ManifestContent, type ManifestDryRunSpec, type ManifestEffectDeclaration, type ManifestEffectMetamodelSpec, type ManifestEffectSchema, type ManifestEnumRuleSpec, type ManifestFilterBySpec, type ManifestImport, type ManifestListResponse, type ManifestOperation, type ManifestPostConditionSpec, type ManifestPropertySpec, type ManifestRelationshipDef, type ManifestReverseSpec, type ManifestStateMachineSpec, type ManifestStateMachineStateSpec, type ManifestStateMachineTransitionSpec, type ManifestValidationOperator, type ManifestValidationRuleSpec, type ManifestVolume, type ModelRef, type PermissionProfile, type PermissionProfileListResponse, type PermissionRules, type Prompt, type PublishEffectsResult, type PublishToolsResult, type RPCRequest, type RPCRequestFromServer, type RPCResponse, type RecordImport, type RecordImportItem, type RecordImportItemStatus, type RecordImportStats, type RecordImportStatus, type RecordObjectOptions, type RecordObjectResult, type RecordUserOptions, type RelationshipInfo, type ResolvedEffectApprovalRequired, type ResolvedEffectBehaviors, type ResolvedEffectDryRun, type ResolvedEffectPostCondition, type ResolvedEffectReverse, type Sandbox, type SandboxListResponse, type SemanticVersionDiff, type SemanticVersionDiffEntry, Session, type SessionHeapEntry, type SessionHeapFieldType, type SessionHeapFieldValue, type SessionHeapList, type SessionHeapSnapshot, type SessionHeapVariable, type Subject, type SyncMessage, type ToolHandler, type ToolInfo, type ToolInvokeParams, type ToolResultParams, type ToolSchema, type ToolWithHandler, type ToolsChangedEvent, type User, type Version, type VersionTag, type VersionTracking, WSClient, type WSClientOptions, type WSDisconnectInfo, type WSReconnectErrorInfo, invokeRegisteredEffect, normalizeEffectBehaviors };
2001
+ export { type APIError, type AccessTokenProvider, type Assignment, type AssignmentListResponse, type Build, type BuildListResponse, type BuildPolicy, type BuildStatus, type ConnectOptions, type ConversationSessionInfo, type CreateEnvironmentData, type CreatePermissionProfileData, type CreateSandboxData, type DefineRelationshipOptions, type DeleteResponse, type DomainState, type EffectHandler, type EffectHandlerContext, type EffectInfo, type EffectInvocationMetadata, type EffectInvocationMode, type EffectSchema, type EffectWithHandler, type EffectsChangedEvent, type EndpointMode, Environment, type EnvironmentData, type EnvironmentListResponse, type EnvironmentRecordImportSummary, Granular, type GranularAuth, type GranularOptions, type GraphQLResult, type InstanceEffectHandler, type InstanceToolHandler, type Job, type JobFeedbackInput, type JobFeedbackMetadata, type JobFeedbackRecord, type JobFeedbackSentiment, type JobFeedbackToolCall, type JobStatus, type JobSubmitResult, type Manifest, type ManifestApprovalRequiredSpec, type ManifestContent, type ManifestDryRunSpec, type ManifestEffectDeclaration, type ManifestEffectMetamodelSpec, type ManifestEffectSchema, type ManifestEnumRuleSpec, type ManifestEventStreamDef, type ManifestEventTypeDef, type ManifestFilterBySpec, type ManifestImport, type ManifestListResponse, type ManifestOperation, type ManifestPostConditionSpec, type ManifestPropertySpec, type ManifestRelationshipDef, type ManifestReverseSpec, type ManifestStateMachineSpec, type ManifestStateMachineStateSpec, type ManifestStateMachineTransitionSpec, type ManifestValidationOperator, type ManifestValidationRuleSpec, type ManifestVolume, type ModelRef, type PermissionProfile, type PermissionProfileListResponse, type PermissionRules, type Prompt, type PublishEffectsResult, type PublishToolsResult, type RPCRequest, type RPCRequestFromServer, type RPCResponse, type RecordImport, type RecordImportItem, type RecordImportItemStatus, type RecordImportStats, type RecordImportStatus, type RecordObjectOptions, type RecordObjectResult, type RecordUserOptions, type RelationshipInfo, type ResolvedEffectApprovalRequired, type ResolvedEffectBehaviors, type ResolvedEffectDryRun, type ResolvedEffectPostCondition, type ResolvedEffectReverse, type Sandbox, type SandboxListResponse, type SemanticVersionDiff, type SemanticVersionDiffEntry, Session, type SessionHeapEntry, type SessionHeapFieldType, type SessionHeapFieldValue, type SessionHeapList, type SessionHeapSnapshot, type SessionHeapVariable, type StreamEvent, type StreamStats, type StreamSubscription, type Subject, type SyncMessage, type ToolHandler, type ToolInfo, type ToolInvokeParams, type ToolResultParams, type ToolSchema, type ToolWithHandler, type ToolsChangedEvent, type User, type Version, type VersionTag, type VersionTracking, WSClient, type WSClientOptions, type WSDisconnectInfo, type WSReconnectErrorInfo, invokeRegisteredEffect, normalizeEffectBehaviors };
package/dist/index.d.ts CHANGED
@@ -359,7 +359,7 @@ interface BuildListResponse {
359
359
  }
360
360
  interface SemanticVersionDiffEntry {
361
361
  operationId: string;
362
- kind: 'create' | 'update' | 'relationship' | 'effect' | 'unknown';
362
+ kind: 'create' | 'update' | 'relationship' | 'effect' | 'eventStream' | 'unknown';
363
363
  changeType: 'added' | 'removed' | 'changed';
364
364
  label: string;
365
365
  additive: boolean;
@@ -1024,6 +1024,22 @@ interface ManifestEffectDeclaration {
1024
1024
  tags?: string[];
1025
1025
  metamodels?: ManifestEffectMetamodelSpec;
1026
1026
  }
1027
+ /**
1028
+ * An event type within an event stream definition
1029
+ */
1030
+ interface ManifestEventTypeDef {
1031
+ name: string;
1032
+ description?: string;
1033
+ payloadSchema: ManifestEffectSchema;
1034
+ }
1035
+ /**
1036
+ * Event stream definition for outgoing typed events
1037
+ */
1038
+ interface ManifestEventStreamDef {
1039
+ name: string;
1040
+ description?: string;
1041
+ eventTypes: ManifestEventTypeDef[];
1042
+ }
1027
1043
  /**
1028
1044
  * A single operation in a manifest volume
1029
1045
  */
@@ -1046,6 +1062,8 @@ interface ManifestOperation {
1046
1062
  defineRelationship?: ManifestRelationshipDef;
1047
1063
  /** Declare a build-owned effect */
1048
1064
  withEffect?: ManifestEffectDeclaration;
1065
+ /** Define an outgoing event stream with typed events */
1066
+ defineEventStream?: ManifestEventStreamDef;
1049
1067
  }
1050
1068
  /**
1051
1069
  * A volume in a manifest
@@ -1098,6 +1116,29 @@ interface APIError {
1098
1116
  interface DeleteResponse {
1099
1117
  deleted: boolean;
1100
1118
  }
1119
+ interface StreamEvent {
1120
+ eventId: string;
1121
+ streamName: string;
1122
+ eventType: string;
1123
+ payload: Record<string, unknown>;
1124
+ environmentId: string;
1125
+ sessionId?: string;
1126
+ subjectId?: string;
1127
+ source: 'sandbox' | 'api';
1128
+ isAcked: boolean;
1129
+ createdAt: number;
1130
+ }
1131
+ interface StreamSubscription {
1132
+ unsubscribe(): void;
1133
+ }
1134
+ interface StreamStats {
1135
+ streamName: string;
1136
+ eventType: string;
1137
+ total: number;
1138
+ last1h: number;
1139
+ last24h: number;
1140
+ unacked: number;
1141
+ }
1101
1142
 
1102
1143
  declare class WSClient {
1103
1144
  private ws;
@@ -1593,6 +1634,8 @@ declare class Environment extends Session {
1593
1634
  private _ensureWorkspaceToolsRoot;
1594
1635
  private _storeEffectSchemas;
1595
1636
  private _applyEffectMetamodels;
1637
+ private _ensureWorkspaceStreamsRoot;
1638
+ private _applyEventStreamDeclaration;
1596
1639
  private _applyEffectDeclaration;
1597
1640
  /**
1598
1641
  * Apply a single manifest operation via GraphQL
@@ -1887,6 +1930,40 @@ declare class Granular {
1887
1930
  create: (sandboxId: string, data: CreateEnvironmentData) => Promise<EnvironmentData>;
1888
1931
  delete: (environmentId: string) => Promise<DeleteResponse>;
1889
1932
  };
1933
+ /**
1934
+ * Event stream operations: query, subscribe, and acknowledge stream events
1935
+ */
1936
+ get streams(): {
1937
+ getEvents: (params: {
1938
+ ontology: string;
1939
+ stream: string;
1940
+ environment?: string;
1941
+ session?: string;
1942
+ eventTypes?: string[];
1943
+ since?: Date;
1944
+ until?: Date;
1945
+ isAcked?: boolean;
1946
+ limit?: number;
1947
+ offset?: number;
1948
+ }) => Promise<StreamEvent[]>;
1949
+ subscribe: (params: {
1950
+ ontology: string;
1951
+ stream: string;
1952
+ environment?: string;
1953
+ session?: string;
1954
+ eventTypes?: string[];
1955
+ since?: Date;
1956
+ onEvent: (event: StreamEvent) => void;
1957
+ onError?: (err: Error) => void;
1958
+ pollIntervalMs?: number;
1959
+ }) => StreamSubscription;
1960
+ ack: (eventId: string) => Promise<void>;
1961
+ ackBatch: (eventIds: string[]) => Promise<void>;
1962
+ getStats: (params: {
1963
+ ontology: string;
1964
+ environment?: string;
1965
+ }) => Promise<StreamStats[]>;
1966
+ };
1890
1967
  /**
1891
1968
  * Subject management
1892
1969
  */
@@ -1905,6 +1982,7 @@ declare class Granular {
1905
1982
  }) => Promise<Subject>;
1906
1983
  get: (id: string) => Promise<Subject>;
1907
1984
  };
1985
+ private _resolveSandboxId;
1908
1986
  /**
1909
1987
  * Make an authenticated API request
1910
1988
  */
@@ -1920,4 +1998,4 @@ type EffectRuntimeRequest = {
1920
1998
  declare function normalizeEffectBehaviors(value?: ManifestEffectMetamodelSpec | ResolvedEffectBehaviors | null): ResolvedEffectBehaviors;
1921
1999
  declare function invokeRegisteredEffect(effectMap: Map<string, ToolWithHandler>, request: EffectRuntimeRequest): Promise<unknown>;
1922
2000
 
1923
- export { type APIError, type AccessTokenProvider, type Assignment, type AssignmentListResponse, type Build, type BuildListResponse, type BuildPolicy, type BuildStatus, type ConnectOptions, type ConversationSessionInfo, type CreateEnvironmentData, type CreatePermissionProfileData, type CreateSandboxData, type DefineRelationshipOptions, type DeleteResponse, type DomainState, type EffectHandler, type EffectHandlerContext, type EffectInfo, type EffectInvocationMetadata, type EffectInvocationMode, type EffectSchema, type EffectWithHandler, type EffectsChangedEvent, type EndpointMode, Environment, type EnvironmentData, type EnvironmentListResponse, type EnvironmentRecordImportSummary, Granular, type GranularAuth, type GranularOptions, type GraphQLResult, type InstanceEffectHandler, type InstanceToolHandler, type Job, type JobFeedbackInput, type JobFeedbackMetadata, type JobFeedbackRecord, type JobFeedbackSentiment, type JobFeedbackToolCall, type JobStatus, type JobSubmitResult, type Manifest, type ManifestApprovalRequiredSpec, type ManifestContent, type ManifestDryRunSpec, type ManifestEffectDeclaration, type ManifestEffectMetamodelSpec, type ManifestEffectSchema, type ManifestEnumRuleSpec, type ManifestFilterBySpec, type ManifestImport, type ManifestListResponse, type ManifestOperation, type ManifestPostConditionSpec, type ManifestPropertySpec, type ManifestRelationshipDef, type ManifestReverseSpec, type ManifestStateMachineSpec, type ManifestStateMachineStateSpec, type ManifestStateMachineTransitionSpec, type ManifestValidationOperator, type ManifestValidationRuleSpec, type ManifestVolume, type ModelRef, type PermissionProfile, type PermissionProfileListResponse, type PermissionRules, type Prompt, type PublishEffectsResult, type PublishToolsResult, type RPCRequest, type RPCRequestFromServer, type RPCResponse, type RecordImport, type RecordImportItem, type RecordImportItemStatus, type RecordImportStats, type RecordImportStatus, type RecordObjectOptions, type RecordObjectResult, type RecordUserOptions, type RelationshipInfo, type ResolvedEffectApprovalRequired, type ResolvedEffectBehaviors, type ResolvedEffectDryRun, type ResolvedEffectPostCondition, type ResolvedEffectReverse, type Sandbox, type SandboxListResponse, type SemanticVersionDiff, type SemanticVersionDiffEntry, Session, type SessionHeapEntry, type SessionHeapFieldType, type SessionHeapFieldValue, type SessionHeapList, type SessionHeapSnapshot, type SessionHeapVariable, type Subject, type SyncMessage, type ToolHandler, type ToolInfo, type ToolInvokeParams, type ToolResultParams, type ToolSchema, type ToolWithHandler, type ToolsChangedEvent, type User, type Version, type VersionTag, type VersionTracking, WSClient, type WSClientOptions, type WSDisconnectInfo, type WSReconnectErrorInfo, invokeRegisteredEffect, normalizeEffectBehaviors };
2001
+ export { type APIError, type AccessTokenProvider, type Assignment, type AssignmentListResponse, type Build, type BuildListResponse, type BuildPolicy, type BuildStatus, type ConnectOptions, type ConversationSessionInfo, type CreateEnvironmentData, type CreatePermissionProfileData, type CreateSandboxData, type DefineRelationshipOptions, type DeleteResponse, type DomainState, type EffectHandler, type EffectHandlerContext, type EffectInfo, type EffectInvocationMetadata, type EffectInvocationMode, type EffectSchema, type EffectWithHandler, type EffectsChangedEvent, type EndpointMode, Environment, type EnvironmentData, type EnvironmentListResponse, type EnvironmentRecordImportSummary, Granular, type GranularAuth, type GranularOptions, type GraphQLResult, type InstanceEffectHandler, type InstanceToolHandler, type Job, type JobFeedbackInput, type JobFeedbackMetadata, type JobFeedbackRecord, type JobFeedbackSentiment, type JobFeedbackToolCall, type JobStatus, type JobSubmitResult, type Manifest, type ManifestApprovalRequiredSpec, type ManifestContent, type ManifestDryRunSpec, type ManifestEffectDeclaration, type ManifestEffectMetamodelSpec, type ManifestEffectSchema, type ManifestEnumRuleSpec, type ManifestEventStreamDef, type ManifestEventTypeDef, type ManifestFilterBySpec, type ManifestImport, type ManifestListResponse, type ManifestOperation, type ManifestPostConditionSpec, type ManifestPropertySpec, type ManifestRelationshipDef, type ManifestReverseSpec, type ManifestStateMachineSpec, type ManifestStateMachineStateSpec, type ManifestStateMachineTransitionSpec, type ManifestValidationOperator, type ManifestValidationRuleSpec, type ManifestVolume, type ModelRef, type PermissionProfile, type PermissionProfileListResponse, type PermissionRules, type Prompt, type PublishEffectsResult, type PublishToolsResult, type RPCRequest, type RPCRequestFromServer, type RPCResponse, type RecordImport, type RecordImportItem, type RecordImportItemStatus, type RecordImportStats, type RecordImportStatus, type RecordObjectOptions, type RecordObjectResult, type RecordUserOptions, type RelationshipInfo, type ResolvedEffectApprovalRequired, type ResolvedEffectBehaviors, type ResolvedEffectDryRun, type ResolvedEffectPostCondition, type ResolvedEffectReverse, type Sandbox, type SandboxListResponse, type SemanticVersionDiff, type SemanticVersionDiffEntry, Session, type SessionHeapEntry, type SessionHeapFieldType, type SessionHeapFieldValue, type SessionHeapList, type SessionHeapSnapshot, type SessionHeapVariable, type StreamEvent, type StreamStats, type StreamSubscription, type Subject, type SyncMessage, type ToolHandler, type ToolInfo, type ToolInvokeParams, type ToolResultParams, type ToolSchema, type ToolWithHandler, type ToolsChangedEvent, type User, type Version, type VersionTag, type VersionTracking, WSClient, type WSClientOptions, type WSDisconnectInfo, type WSReconnectErrorInfo, invokeRegisteredEffect, normalizeEffectBehaviors };
package/dist/index.js CHANGED
@@ -11837,6 +11837,70 @@ var Environment = class extends Session {
11837
11837
  await this._runGraphql(mutation.query, mutation.label);
11838
11838
  }
11839
11839
  }
11840
+ async _ensureWorkspaceStreamsRoot() {
11841
+ await this._runGraphql(
11842
+ `mutation { create_model(path: "workspace", label: "workspace") { model { path } } }`,
11843
+ "ensure workspace"
11844
+ ).catch((error) => {
11845
+ if (!error.message.includes("already exists")) throw error;
11846
+ });
11847
+ await this._runGraphql(
11848
+ `mutation { at(path: "workspace") { create_submodel(subpath: "streams", label: "Streams") { model { path } } } }`,
11849
+ "ensure workspace:streams"
11850
+ ).catch((error) => {
11851
+ if (!error.message.includes("already exists")) throw error;
11852
+ });
11853
+ }
11854
+ async _applyEventStreamDeclaration(stream) {
11855
+ await this._ensureWorkspaceStreamsRoot();
11856
+ const streamPath = `workspace:streams:${stream.name}`;
11857
+ await this._runGraphql(
11858
+ `mutation { at(path: "workspace:streams") { create_submodel(subpath: ${JSON.stringify(stream.name)}, label: ${JSON.stringify(stream.name)}) { model { path } } } }`,
11859
+ `create stream ${stream.name}`
11860
+ ).catch((error) => {
11861
+ if (!error.message.includes("already exists")) throw error;
11862
+ });
11863
+ if (stream.description) {
11864
+ await this._runGraphql(
11865
+ `mutation { at(path: ${JSON.stringify(streamPath)}) { set_description(description: ${JSON.stringify(stream.description)}) { done } } }`,
11866
+ `set stream description on ${streamPath}`
11867
+ );
11868
+ }
11869
+ for (const eventType of stream.eventTypes) {
11870
+ const typePath = `${streamPath}:${eventType.name}`;
11871
+ await this._runGraphql(
11872
+ `mutation { at(path: ${JSON.stringify(streamPath)}) { create_submodel(subpath: ${JSON.stringify(eventType.name)}, label: ${JSON.stringify(eventType.name)}) { model { path } } } }`,
11873
+ `create event type ${eventType.name} on ${streamPath}`
11874
+ ).catch((error) => {
11875
+ if (!error.message.includes("already exists")) throw error;
11876
+ });
11877
+ if (eventType.description) {
11878
+ await this._runGraphql(
11879
+ `mutation { at(path: ${JSON.stringify(typePath)}) { set_description(description: ${JSON.stringify(eventType.description)}) { done } } }`,
11880
+ `set event type description on ${typePath}`
11881
+ );
11882
+ }
11883
+ if (eventType.payloadSchema?.properties) {
11884
+ const fieldSpecs = {};
11885
+ for (const [propName, propSchema] of Object.entries(eventType.payloadSchema.properties)) {
11886
+ const schema = propSchema;
11887
+ fieldSpecs[propName] = {
11888
+ type: schema.type ?? "string",
11889
+ description: schema.description
11890
+ };
11891
+ }
11892
+ await this._applyFields(typePath, fieldSpecs);
11893
+ }
11894
+ if (eventType.payloadSchema?.required?.length) {
11895
+ await this._runGraphql(
11896
+ `mutation { at(path: ${JSON.stringify(typePath)}) { create_submodel(subpath: "required", label: "required") { set_string_value(value: ${JSON.stringify(JSON.stringify(eventType.payloadSchema.required))}) { done } } } }`,
11897
+ `store required fields on ${typePath}`
11898
+ ).catch((error) => {
11899
+ if (!error.message.includes("already exists")) throw error;
11900
+ });
11901
+ }
11902
+ }
11903
+ }
11840
11904
  async _applyEffectDeclaration(effect, aliasMap) {
11841
11905
  let containerPath = "workspace:tools:declared";
11842
11906
  if (effect.attachedClass) {
@@ -11924,6 +11988,9 @@ var Environment = class extends Session {
11924
11988
  if (op.withEffect) {
11925
11989
  await this._applyEffectDeclaration(op.withEffect, aliasMap);
11926
11990
  }
11991
+ if (op.defineEventStream) {
11992
+ await this._applyEventStreamDeclaration(op.defineEventStream);
11993
+ }
11927
11994
  }
11928
11995
  /**
11929
11996
  * Apply field definitions (has) to a model via GraphQL
@@ -12896,6 +12963,107 @@ var Granular = class _Granular {
12896
12963
  }
12897
12964
  };
12898
12965
  }
12966
+ /**
12967
+ * Event stream operations: query, subscribe, and acknowledge stream events
12968
+ */
12969
+ get streams() {
12970
+ return {
12971
+ getEvents: async (params) => {
12972
+ const sandbox = await this._resolveSandboxId(params.ontology);
12973
+ const query = new URLSearchParams({ sandboxId: sandbox });
12974
+ if (params.environment) query.set("environmentId", params.environment);
12975
+ if (params.session) query.set("sessionId", params.session);
12976
+ if (params.stream) query.set("streamName", params.stream);
12977
+ if (params.eventTypes && params.eventTypes.length > 0) {
12978
+ query.set("eventTypes", params.eventTypes.join(","));
12979
+ }
12980
+ if (params.since) query.set("since", params.since.toISOString());
12981
+ if (params.until) query.set("until", params.until.toISOString());
12982
+ if (params.isAcked !== void 0) query.set("isAcked", params.isAcked ? "1" : "0");
12983
+ if (params.limit) query.set("limit", String(params.limit));
12984
+ if (params.offset) query.set("offset", String(params.offset));
12985
+ const result = await this.request(`/control/stream-events?${query.toString()}`);
12986
+ return (result.items || []).map((row) => ({
12987
+ eventId: row.event_id,
12988
+ streamName: row.stream_name,
12989
+ eventType: row.event_type,
12990
+ payload: typeof row.payload === "string" ? JSON.parse(row.payload) : row.payload,
12991
+ environmentId: row.environment_id,
12992
+ sessionId: row.session_id,
12993
+ subjectId: row.subject_id,
12994
+ source: row.source,
12995
+ isAcked: Boolean(row.is_acked),
12996
+ createdAt: row.created_at
12997
+ }));
12998
+ },
12999
+ subscribe: (params) => {
13000
+ const interval = params.pollIntervalMs ?? 5e3;
13001
+ let cursor = params.since || /* @__PURE__ */ new Date();
13002
+ let running = true;
13003
+ const seenEventIds = /* @__PURE__ */ new Set();
13004
+ const poll = async () => {
13005
+ while (running) {
13006
+ try {
13007
+ const events = await this.streams.getEvents({
13008
+ ontology: params.ontology,
13009
+ stream: params.stream,
13010
+ environment: params.environment,
13011
+ session: params.session,
13012
+ eventTypes: params.eventTypes,
13013
+ since: cursor,
13014
+ limit: 100
13015
+ });
13016
+ const orderedEvents = [...events].sort((a, b) => a.createdAt - b.createdAt);
13017
+ for (const event of orderedEvents) {
13018
+ if (seenEventIds.has(event.eventId)) {
13019
+ continue;
13020
+ }
13021
+ seenEventIds.add(event.eventId);
13022
+ const eventTime = new Date(event.createdAt * 1e3);
13023
+ if (eventTime > cursor) {
13024
+ cursor = eventTime;
13025
+ }
13026
+ params.onEvent(event);
13027
+ }
13028
+ } catch (err) {
13029
+ params.onError?.(err instanceof Error ? err : new Error(String(err)));
13030
+ }
13031
+ await new Promise((resolve) => setTimeout(resolve, interval));
13032
+ }
13033
+ };
13034
+ poll();
13035
+ return { unsubscribe: () => {
13036
+ running = false;
13037
+ } };
13038
+ },
13039
+ ack: async (eventId) => {
13040
+ await this.request("/control/stream-events/ack", {
13041
+ method: "POST",
13042
+ body: JSON.stringify({ eventIds: [eventId] })
13043
+ });
13044
+ },
13045
+ ackBatch: async (eventIds) => {
13046
+ await this.request("/control/stream-events/ack", {
13047
+ method: "POST",
13048
+ body: JSON.stringify({ eventIds })
13049
+ });
13050
+ },
13051
+ getStats: async (params) => {
13052
+ const sandbox = await this._resolveSandboxId(params.ontology);
13053
+ const query = new URLSearchParams({ sandboxId: sandbox });
13054
+ if (params.environment) query.set("environmentId", params.environment);
13055
+ const result = await this.request(`/control/stream-events/stats?${query.toString()}`);
13056
+ return (result.items || []).map((row) => ({
13057
+ streamName: row.stream_name,
13058
+ eventType: row.event_type,
13059
+ total: Number(row.total),
13060
+ last1h: Number(row.last_1h),
13061
+ last24h: Number(row.last_24h),
13062
+ unacked: Number(row.unacked)
13063
+ }));
13064
+ }
13065
+ };
13066
+ }
12899
13067
  /**
12900
13068
  * Subject management
12901
13069
  */
@@ -12929,6 +13097,12 @@ var Granular = class _Granular {
12929
13097
  }
12930
13098
  };
12931
13099
  }
13100
+ async _resolveSandboxId(ontologyNameOrId) {
13101
+ if (ontologyNameOrId.startsWith("sbx_")) return ontologyNameOrId;
13102
+ const result = await this.request(`/control/sandboxes?name=${encodeURIComponent(ontologyNameOrId)}`);
13103
+ if (result.items.length === 0) throw new Error(`Ontology not found: ${ontologyNameOrId}`);
13104
+ return result.items[0].sandboxId;
13105
+ }
12932
13106
  /**
12933
13107
  * Make an authenticated API request
12934
13108
  */