@atlanai/sdk 0.2.2 → 0.2.4

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.
Files changed (148) hide show
  1. package/README.md +6 -2
  2. package/dist/client.d.ts +20 -3
  3. package/dist/client.js +130 -9
  4. package/dist/errors.d.ts +10 -0
  5. package/dist/errors.js +34 -1
  6. package/dist/evals.d.ts +135 -8
  7. package/dist/evals.js +1004 -73
  8. package/dist/index.d.ts +3 -2
  9. package/dist/index.js +7 -1
  10. package/dist/manifest.json +84 -11
  11. package/dist/raw/agent/apis/AgentsApi.d.ts +29 -0
  12. package/dist/raw/agent/apis/AgentsApi.js +62 -1
  13. package/dist/raw/agent/apis/SessionsApi.d.ts +2 -2
  14. package/dist/raw/agent/apis/SessionsApi.js +2 -2
  15. package/dist/raw/agent/models/AgentAgentArtifactView.d.ts +48 -0
  16. package/dist/raw/agent/models/AgentAgentArtifactView.js +13 -0
  17. package/dist/raw/agent/models/AgentAgentEnvironmentArtifactView.d.ts +12 -0
  18. package/dist/raw/agent/models/AgentAgentEnvironmentArtifactView.js +2 -0
  19. package/dist/raw/agent/models/AgentAgentEnvironmentMeta.d.ts +12 -0
  20. package/dist/raw/agent/models/AgentAgentEnvironmentMeta.js +2 -0
  21. package/dist/raw/agent/models/AgentAgentMeta.d.ts +48 -0
  22. package/dist/raw/agent/models/AgentAgentMeta.js +13 -0
  23. package/dist/raw/agent/models/AgentAgentProviderArtifactView.d.ts +55 -2
  24. package/dist/raw/agent/models/AgentAgentProviderArtifactView.js +8 -0
  25. package/dist/raw/agent/models/AgentAgentProviderCreate.d.ts +24 -3
  26. package/dist/raw/agent/models/AgentAgentProviderCreate.js +4 -0
  27. package/dist/raw/agent/models/AgentAgentProviderMeta.d.ts +56 -13
  28. package/dist/raw/agent/models/AgentAgentProviderMeta.js +8 -0
  29. package/dist/raw/agent/models/AgentAgentProviderPatch.d.ts +13 -0
  30. package/dist/raw/agent/models/AgentAgentProviderPatch.js +4 -0
  31. package/dist/raw/agent/models/AgentAgentProviderType.d.ts +19 -9
  32. package/dist/raw/agent/models/AgentAgentProviderType.js +18 -8
  33. package/dist/raw/agent/models/AgentListAgentFrameworks401Response.d.ts +1 -0
  34. package/dist/raw/agent/models/AgentListAgentFrameworks401Response.js +1 -0
  35. package/dist/raw/agent/models/AgentPageSessionEventView.d.ts +3 -3
  36. package/dist/raw/agent/models/AgentPageSessionEventView.js +3 -3
  37. package/dist/raw/agent/models/AgentRemoteSessionEvent.d.ts +38 -0
  38. package/dist/raw/agent/models/AgentRemoteSessionEvent.js +58 -0
  39. package/dist/raw/agent/models/AgentSessionArtifactView.d.ts +25 -0
  40. package/dist/raw/agent/models/AgentSessionArtifactView.js +2 -0
  41. package/dist/raw/agent/models/AgentSessionEventView.d.ts +30 -0
  42. package/dist/raw/agent/models/AgentSessionEventView.js +57 -0
  43. package/dist/raw/agent/models/AgentSessionMeta.d.ts +25 -0
  44. package/dist/raw/agent/models/AgentSessionMeta.js +2 -0
  45. package/dist/raw/agent/models/AgentSessionStreamFrame.d.ts +8 -6
  46. package/dist/raw/agent/models/AgentSessionStreamFrame.js +7 -0
  47. package/dist/raw/agent/models/AgentSyncState.d.ts +27 -0
  48. package/dist/raw/agent/models/AgentSyncState.js +55 -0
  49. package/dist/raw/agent/models/TriggerBody.d.ts +52 -0
  50. package/dist/raw/agent/models/TriggerBody.js +58 -0
  51. package/dist/raw/agent/models/index.d.ts +4 -1
  52. package/dist/raw/agent/models/index.js +4 -1
  53. package/dist/raw/eval/models/EvalListDatasets401Response.d.ts +1 -0
  54. package/dist/raw/eval/models/EvalListDatasets401Response.js +1 -0
  55. package/dist/raw/file/models/FileList401Response.d.ts +1 -0
  56. package/dist/raw/file/models/FileList401Response.js +1 -0
  57. package/dist/raw/mcp/apis/ServersApi.d.ts +2 -2
  58. package/dist/raw/mcp/apis/ServersApi.js +2 -2
  59. package/dist/raw/mcp/models/McpConnectionState.d.ts +2 -1
  60. package/dist/raw/mcp/models/McpConnectionState.js +2 -1
  61. package/dist/raw/mcp/models/McpListServers401Response.d.ts +1 -0
  62. package/dist/raw/mcp/models/McpListServers401Response.js +1 -0
  63. package/dist/raw/mcp/models/McpServerTestResponse.d.ts +13 -2
  64. package/dist/raw/model/models/ModelListProviders401Response.d.ts +1 -0
  65. package/dist/raw/model/models/ModelListProviders401Response.js +1 -0
  66. package/dist/raw/registry/apis/WorkspacesApi.d.ts +28 -0
  67. package/dist/raw/registry/apis/WorkspacesApi.js +61 -1
  68. package/dist/raw/registry/models/CreateWorkspaceBody.d.ts +9 -0
  69. package/dist/raw/registry/models/CreateWorkspaceBody.js +2 -0
  70. package/dist/raw/registry/models/RegistryAggregate401Response.d.ts +1 -0
  71. package/dist/raw/registry/models/RegistryAggregate401Response.js +1 -0
  72. package/dist/raw/registry/models/RegistryWorkspaceView.d.ts +9 -0
  73. package/dist/raw/registry/models/RegistryWorkspaceView.js +4 -0
  74. package/dist/raw/registry/models/SearchRequest.d.ts +1 -1
  75. package/dist/raw/registry/models/SetVisibilityBody.d.ts +33 -0
  76. package/dist/raw/registry/models/SetVisibilityBody.js +50 -0
  77. package/dist/raw/registry/models/index.d.ts +1 -0
  78. package/dist/raw/registry/models/index.js +1 -0
  79. package/dist/raw/secret/apis/OauthApi.d.ts +143 -0
  80. package/dist/raw/secret/apis/OauthApi.js +335 -0
  81. package/dist/raw/secret/apis/index.d.ts +1 -0
  82. package/dist/raw/secret/apis/index.js +19 -0
  83. package/dist/raw/secret/index.d.ts +1 -0
  84. package/dist/raw/secret/index.js +1 -0
  85. package/dist/raw/secret/models/GatewayOauthCompleteRequest.d.ts +32 -0
  86. package/dist/raw/secret/models/GatewayOauthCompleteRequest.js +50 -0
  87. package/dist/raw/secret/models/GatewayOauthCompletion.d.ts +46 -0
  88. package/dist/raw/secret/models/GatewayOauthCompletion.js +55 -0
  89. package/dist/raw/secret/models/GatewayOauthConnection.d.ts +83 -0
  90. package/dist/raw/secret/models/GatewayOauthConnection.js +83 -0
  91. package/dist/raw/secret/models/GatewayOauthOwner.d.ts +31 -0
  92. package/dist/raw/secret/models/GatewayOauthOwner.js +59 -0
  93. package/dist/raw/secret/models/GatewayOauthProviderView.d.ts +69 -0
  94. package/dist/raw/secret/models/GatewayOauthProviderView.js +69 -0
  95. package/dist/raw/secret/models/GatewayOauthStartRequest.d.ts +52 -0
  96. package/dist/raw/secret/models/GatewayOauthStartRequest.js +59 -0
  97. package/dist/raw/secret/models/GatewayOauthStarted.d.ts +39 -0
  98. package/dist/raw/secret/models/GatewayOauthStarted.js +54 -0
  99. package/dist/raw/secret/models/SecretCompleteOauth400Response.d.ts +70 -0
  100. package/dist/raw/secret/models/SecretCompleteOauth400Response.js +80 -0
  101. package/dist/raw/secret/models/SecretCompleteOauth413Response.d.ts +64 -0
  102. package/dist/raw/secret/models/SecretCompleteOauth413Response.js +74 -0
  103. package/dist/raw/secret/models/SecretCompleteOauth415Response.d.ts +64 -0
  104. package/dist/raw/secret/models/SecretCompleteOauth415Response.js +74 -0
  105. package/dist/raw/secret/models/SecretCompleteOauth422Response.d.ts +63 -0
  106. package/dist/raw/secret/models/SecretCompleteOauth422Response.js +75 -0
  107. package/dist/raw/secret/models/SecretDisconnectOauth400Response.d.ts +67 -0
  108. package/dist/raw/secret/models/SecretDisconnectOauth400Response.js +77 -0
  109. package/dist/raw/secret/models/SecretOauthCallback400Response.d.ts +68 -0
  110. package/dist/raw/secret/models/SecretOauthCallback400Response.js +78 -0
  111. package/dist/raw/secret/models/SecretOauthCallback401Response.d.ts +80 -0
  112. package/dist/raw/secret/models/SecretOauthCallback401Response.js +90 -0
  113. package/dist/raw/secret/models/SecretOauthCallback403Response.d.ts +66 -0
  114. package/dist/raw/secret/models/SecretOauthCallback403Response.js +76 -0
  115. package/dist/raw/secret/models/SecretOauthCallback404Response.d.ts +65 -0
  116. package/dist/raw/secret/models/SecretOauthCallback404Response.js +75 -0
  117. package/dist/raw/secret/models/SecretOauthCallback500Response.d.ts +64 -0
  118. package/dist/raw/secret/models/SecretOauthCallback500Response.js +74 -0
  119. package/dist/raw/secret/models/SecretOauthCallback503Response.d.ts +66 -0
  120. package/dist/raw/secret/models/SecretOauthCallback503Response.js +76 -0
  121. package/dist/raw/secret/models/SecretOauthCallback504Response.d.ts +63 -0
  122. package/dist/raw/secret/models/SecretOauthCallback504Response.js +75 -0
  123. package/dist/raw/secret/models/index.d.ts +19 -0
  124. package/dist/raw/secret/models/index.js +19 -0
  125. package/dist/raw/skill/models/SkillInsightSchemas401Response.d.ts +1 -0
  126. package/dist/raw/skill/models/SkillInsightSchemas401Response.js +1 -0
  127. package/dist/resource-types.d.ts +670 -0
  128. package/dist/resource-types.js +2 -0
  129. package/dist/resources.d.ts +10 -0
  130. package/dist/resources.js +54 -4
  131. package/dist/resources.json +86 -0
  132. package/dist/tracing/client.d.ts +8 -1
  133. package/dist/tracing/client.js +43 -16
  134. package/dist/tracing/config.d.ts +3 -1
  135. package/dist/tracing/config.js +7 -2
  136. package/dist/tracing/exporter.d.ts +19 -1
  137. package/dist/tracing/exporter.js +56 -14
  138. package/dist/tracing/propagation.d.ts +2 -0
  139. package/dist/tracing/propagation.js +16 -0
  140. package/dist/tracing/semconv.d.ts +4 -0
  141. package/dist/tracing/semconv.js +14 -2
  142. package/dist/tracing/spans.d.ts +2 -0
  143. package/dist/tracing/spans.js +12 -1
  144. package/dist/tracing/version.d.ts +1 -1
  145. package/dist/tracing/version.js +1 -1
  146. package/package.json +1 -1
  147. package/dist/raw/agent/models/Box.d.ts +0 -342
  148. package/dist/raw/agent/models/Box.js +0 -167
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -60,6 +60,16 @@ export interface Resource {
60
60
  readonly operations: Readonly<Record<string, string>>;
61
61
  readonly [member: string]: ResourceOperation | Resource | string | Readonly<Record<string, string>>;
62
62
  }
63
+ /**
64
+ * Refuse to return a bulk write that achieved nothing as a success.
65
+ *
66
+ * A bulk endpoint answers 207: each slot carries its own status, and partial
67
+ * success is the point, so one failed slot is the caller's business and is
68
+ * left alone. A batch where no slot succeeded is different. It changed
69
+ * nothing, it is never what the caller wanted, and returning it as an ordinary
70
+ * value is how a whole dataset ends up silently empty.
71
+ */
72
+ export declare function raiseIfNothingSucceeded(result: unknown): void;
63
73
  /**
64
74
  * Build the top-level resources, nesting children under their parents.
65
75
  *
package/dist/resources.js CHANGED
@@ -17,8 +17,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  };
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.resourceMap = void 0;
20
+ exports.raiseIfNothingSucceeded = raiseIfNothingSucceeded;
20
21
  exports.buildResources = buildResources;
21
22
  const resources_json_1 = __importDefault(require("./resources.json"));
23
+ const errors_1 = require("./errors");
22
24
  const SCHEMA_VERSION = 1;
23
25
  exports.resourceMap = resources_json_1.default;
24
26
  if (exports.resourceMap.schema_version !== SCHEMA_VERSION) {
@@ -49,6 +51,53 @@ function isPlainObject(value) {
49
51
  * guessed: a lone object argument carrying any of the expected property names
50
52
  * is passed straight through.
51
53
  */
54
+ /** The per-item status on a multi-status slot, if this is one. */
55
+ function slotStatus(item) {
56
+ if (!isPlainObject(item))
57
+ return undefined;
58
+ const status = item.statusCode ?? item.status_code;
59
+ return typeof status === "number" ? status : undefined;
60
+ }
61
+ /**
62
+ * Refuse to return a bulk write that achieved nothing as a success.
63
+ *
64
+ * A bulk endpoint answers 207: each slot carries its own status, and partial
65
+ * success is the point, so one failed slot is the caller's business and is
66
+ * left alone. A batch where no slot succeeded is different. It changed
67
+ * nothing, it is never what the caller wanted, and returning it as an ordinary
68
+ * value is how a whole dataset ends up silently empty.
69
+ */
70
+ function raiseIfNothingSucceeded(result) {
71
+ const items = isPlainObject(result) ? result.items : undefined;
72
+ if (!Array.isArray(items) || items.length === 0)
73
+ return;
74
+ const statuses = items.map(slotStatus);
75
+ // Only a multi-status envelope: every slot has to carry its own status.
76
+ if (statuses.some((status) => status === undefined))
77
+ return;
78
+ if (statuses.some((status) => status !== undefined && status >= 200 && status < 300))
79
+ return;
80
+ const codes = [...new Set(statuses.map(String))].sort();
81
+ const explanation = `none of the ${items.length} items in this batch was accepted ` +
82
+ `(per-item status: ${codes.join(", ")}); read items[].error for why`;
83
+ throw new errors_1.AtlanAPIError({
84
+ status: statuses[0] ?? 207,
85
+ code: "bulk_all_rejected",
86
+ title: "Every item in the batch was rejected",
87
+ detail: explanation,
88
+ // As a hint, not a detail: this text is client-authored, so the rule
89
+ // keeping server prose out of the message does not apply.
90
+ hint: explanation,
91
+ });
92
+ }
93
+ /** Wrap an operation so a batch that achieved nothing cannot return quietly. */
94
+ function guarded(operation) {
95
+ return (async (...args) => {
96
+ const result = await operation(...args);
97
+ raiseIfNothingSucceeded(result);
98
+ return result;
99
+ });
100
+ }
52
101
  function positionalCall(forwarded, detail, workspace) {
53
102
  const bodyKey = detail.typescript_body;
54
103
  const pathKeys = [...detail.route.matchAll(/\{(\w+)\}/g)].map((match) => camelCase(match[1]));
@@ -56,11 +105,12 @@ function positionalCall(forwarded, detail, workspace) {
56
105
  // alone let `get(agentId)` pass a bare string where the generated client
57
106
  // wanted an object: no error, and the wrong resource fetched.
58
107
  const workspaceKey = detail.workspace_parameter?.typescript;
59
- if (bodyKey === undefined && pathKeys.length === 0 && workspaceKey === undefined)
60
- return forwarded;
108
+ if (bodyKey === undefined && pathKeys.length === 0 && workspaceKey === undefined) {
109
+ return guarded(forwarded);
110
+ }
61
111
  const arity = pathKeys.length + (bodyKey === undefined ? 0 : 1);
62
112
  const expected = new Set(bodyKey === undefined ? pathKeys : [...pathKeys, bodyKey]);
63
- return ((...args) => {
113
+ return guarded(((...args) => {
64
114
  const values = args;
65
115
  if (values.length === 1 && isPlainObject(values[0])) {
66
116
  const keys = Object.keys(values[0]);
@@ -81,7 +131,7 @@ function positionalCall(forwarded, detail, workspace) {
81
131
  if (workspaceKey !== undefined && workspace !== undefined)
82
132
  options[workspaceKey] = workspace;
83
133
  return forwarded(options);
84
- });
134
+ }));
85
135
  }
86
136
  function buildResource(path, entry, service, children, workspace) {
87
137
  const operations = {};
@@ -253,6 +253,15 @@
253
253
  },
254
254
  "agents.sessions": {
255
255
  "methods": {
256
+ "create": {
257
+ "method_camel": "create",
258
+ "operation_id": "agent.createSession",
259
+ "python": "agent_create_session",
260
+ "route": "POST /agent/v1/agents/{agent_id}/sessions",
261
+ "summary": "Trigger an agent run",
262
+ "typescript": "agentCreateSession",
263
+ "typescript_body": "triggerBody"
264
+ },
256
265
  "list": {
257
266
  "method_camel": "list",
258
267
  "operation_id": "agent.listAgentSessions",
@@ -466,6 +475,42 @@
466
475
  "service": "registry",
467
476
  "typescript": "auth"
468
477
  },
478
+ "callback": {
479
+ "methods": {
480
+ "oauth": {
481
+ "method_camel": "oauth",
482
+ "operation_id": "secret.oauthCallback",
483
+ "python": "secret_oauth_callback",
484
+ "route": "GET /secret/v1/oauth/callback/{provider}",
485
+ "summary": "`GET /<ext>/v1/oauth/callback/{provider}` \u2014 the provider's redirect target.",
486
+ "typescript": "secretOauthCallback"
487
+ }
488
+ },
489
+ "service": "secret",
490
+ "typescript": "callback"
491
+ },
492
+ "connections": {
493
+ "methods": {
494
+ "disconnect_oauth": {
495
+ "method_camel": "disconnectOauth",
496
+ "operation_id": "secret.disconnectOauth",
497
+ "python": "secret_disconnect_oauth",
498
+ "route": "DELETE /secret/v1/oauth/connections/{secret_id}",
499
+ "summary": "`DELETE /<ext>/v1/oauth/connections/{secret_id}`.",
500
+ "typescript": "secretDisconnectOauth"
501
+ },
502
+ "list_oauth": {
503
+ "method_camel": "listOauth",
504
+ "operation_id": "secret.listOauthConnections",
505
+ "python": "secret_list_oauth_connections",
506
+ "route": "GET /secret/v1/oauth/connections",
507
+ "summary": "`GET /<ext>/v1/oauth/connections`.",
508
+ "typescript": "secretListOauthConnections"
509
+ }
510
+ },
511
+ "service": "secret",
512
+ "typescript": "connections"
513
+ },
469
514
  "datasets": {
470
515
  "methods": {
471
516
  "archive": {
@@ -1163,6 +1208,38 @@
1163
1208
  "service": "model",
1164
1209
  "typescript": "modelProviders"
1165
1210
  },
1211
+ "oauth": {
1212
+ "methods": {
1213
+ "complete": {
1214
+ "method_camel": "complete",
1215
+ "operation_id": "secret.completeOauth",
1216
+ "python": "secret_complete_oauth",
1217
+ "route": "POST /secret/v1/oauth/complete",
1218
+ "summary": "`POST /<ext>/v1/oauth/complete` \u2014 polled until it answers `connected`.",
1219
+ "typescript": "secretCompleteOauth",
1220
+ "typescript_body": "gatewayOauthCompleteRequest"
1221
+ },
1222
+ "list_providers": {
1223
+ "method_camel": "listProviders",
1224
+ "operation_id": "secret.listOauthProviders",
1225
+ "python": "secret_list_oauth_providers",
1226
+ "route": "GET /secret/v1/oauth/providers",
1227
+ "summary": "`GET /<ext>/v1/oauth/providers` \u2014 what can be connected, and the callback URL\nto register for each.",
1228
+ "typescript": "secretListOauthProviders"
1229
+ },
1230
+ "start": {
1231
+ "method_camel": "start",
1232
+ "operation_id": "secret.startOauth",
1233
+ "python": "secret_start_oauth",
1234
+ "route": "POST /secret/v1/oauth/start",
1235
+ "summary": "`POST /<ext>/v1/oauth/start`.",
1236
+ "typescript": "secretStartOauth",
1237
+ "typescript_body": "gatewayOauthStartRequest"
1238
+ }
1239
+ },
1240
+ "service": "secret",
1241
+ "typescript": "oauth"
1242
+ },
1166
1243
  "openai": {
1167
1244
  "methods": {
1168
1245
  "chat_completions": {
@@ -2136,6 +2213,15 @@
2136
2213
  "summary": "Recommend workspaces to join",
2137
2214
  "typescript": "registryListWorkspaceRecommendations"
2138
2215
  },
2216
+ "set_visibility": {
2217
+ "method_camel": "setVisibility",
2218
+ "operation_id": "registry.setWorkspaceVisibility",
2219
+ "python": "registry_set_workspace_visibility",
2220
+ "route": "PATCH /registry/v1/workspaces/{workspace_id}/visibility",
2221
+ "summary": "Change a workspace's visibility",
2222
+ "typescript": "registrySetWorkspaceVisibility",
2223
+ "typescript_body": "setVisibilityBody"
2224
+ },
2139
2225
  "update": {
2140
2226
  "method_camel": "update",
2141
2227
  "operation_id": "registry.updateWorkspace",
@@ -15,6 +15,7 @@
15
15
  import { type Tracer, type TimeInput } from "@opentelemetry/api";
16
16
  import { BasicTracerProvider, type SpanExporter } from "@opentelemetry/sdk-trace-base";
17
17
  import { type ConfigOptions, type ResolvedConfig } from "./config.js";
18
+ import { type ExportHealth } from "./exporter.js";
18
19
  import { type MaskFunction, type MaskOtelSpansFunction } from "./masking.js";
19
20
  import { AtlanSpanProcessor } from "./processor.js";
20
21
  import { type ShouldExportSpan } from "./span-filter.js";
@@ -70,12 +71,18 @@ export declare class AtlanAI {
70
71
  private readonly mask;
71
72
  private readonly ownsGlobal;
72
73
  private readonly waitUntil;
74
+ private readonly trackedExporter;
73
75
  private shutdownDone;
74
76
  constructor(config: ResolvedConfig, options?: InitOptions);
75
77
  get isEnabled(): boolean;
76
78
  /** The SDK's TracerProvider (null when disabled). Third-party tracers
77
79
  * acquired from it flow through the Atlan pipeline (allowlist + enrichment). */
78
80
  get tracerProvider(): BasicTracerProvider | null;
81
+ /** Current delivery health without endpoint or credential details. */
82
+ get exportHealth(): ExportHealth | {
83
+ status: "disabled";
84
+ exportFailures: 0;
85
+ };
79
86
  getTracer(): Tracer;
80
87
  /** Return the active OTel span through the Atlan ergonomic span surface. */
81
88
  currentSpan(): AtlanSpan;
@@ -98,7 +105,7 @@ export declare class AtlanAI {
98
105
  shutdown(): Promise<void>;
99
106
  }
100
107
  /**
101
- * Initialize the SDK. Idempotent per API key (SPEC §10.2). Throws
108
+ * Initialize the SDK. Idempotent per pipeline identity (SPEC §10.2). Throws
102
109
  * AtlanConfigError only when an Atlan endpoint is configured without a
103
110
  * workspace (SPEC §2.4); all other misconfiguration logs a warning and returns
104
111
  * a disabled, no-op client.
@@ -72,7 +72,7 @@ function registry() {
72
72
  const host = globalThis;
73
73
  let existing = host[REGISTRY_SLOT];
74
74
  if (!existing) {
75
- existing = { clients: new Map(), defaultKey: undefined };
75
+ existing = { clients: new Map(), defaultKey: undefined, exitHookInstalled: false };
76
76
  try {
77
77
  Object.defineProperty(host, REGISTRY_SLOT, {
78
78
  value: existing,
@@ -85,10 +85,25 @@ function registry() {
85
85
  host[REGISTRY_SLOT] = existing;
86
86
  }
87
87
  }
88
+ if (!existing.exitHookInstalled) {
89
+ existing.exitHookInstalled = true;
90
+ const clients = existing.clients;
91
+ isomorph_js_1.iso.onExit(() => {
92
+ for (const client of clients.values()) {
93
+ void client.flush().catch(() => undefined);
94
+ }
95
+ });
96
+ }
88
97
  return existing;
89
98
  }
90
- function clientKey(apiKey) {
91
- return apiKey ?? "::anon::";
99
+ function clientKey(config) {
100
+ return [
101
+ config.apiKey ?? "::anon::",
102
+ config.mode,
103
+ config.baseUrl,
104
+ config.workspaceId ?? "",
105
+ config.serviceName ?? "",
106
+ ].join("\u0000");
92
107
  }
93
108
  const TRACE_ID_RE = /^[0-9a-f]{32}$/;
94
109
  const SPAN_ID_RE = /^[0-9a-f]{16}$/;
@@ -196,6 +211,7 @@ class AtlanAI {
196
211
  mask;
197
212
  ownsGlobal = false;
198
213
  waitUntil;
214
+ trackedExporter = null;
199
215
  shutdownDone = false;
200
216
  constructor(config, options = {}) {
201
217
  this.config = config;
@@ -207,7 +223,8 @@ class AtlanAI {
207
223
  if (options.maskOtelSpans !== undefined) {
208
224
  exporter = new masking_js_1.MaskingSpanExporter(exporter, options.maskOtelSpans);
209
225
  }
210
- this.spanProcessor = new processor_js_1.AtlanSpanProcessor(exporter, {
226
+ this.trackedExporter = new exporter_js_1.TrackingSpanExporter(exporter);
227
+ this.spanProcessor = new processor_js_1.AtlanSpanProcessor(this.trackedExporter, {
211
228
  flushAt: config.debug ? 1 : config.flushAt,
212
229
  flushIntervalS: config.debug ? 0.1 : config.flushIntervalS,
213
230
  timeoutS: config.timeoutS,
@@ -238,9 +255,6 @@ class AtlanAI {
238
255
  this.ownsGlobal = true;
239
256
  }
240
257
  }
241
- isomorph_js_1.iso.onExit(() => {
242
- void this.flush().catch(() => undefined);
243
- });
244
258
  }
245
259
  get isEnabled() {
246
260
  return this.spanProcessor !== null;
@@ -250,6 +264,10 @@ class AtlanAI {
250
264
  get tracerProvider() {
251
265
  return this.provider;
252
266
  }
267
+ /** Current delivery health without endpoint or credential details. */
268
+ get exportHealth() {
269
+ return this.trackedExporter?.health ?? { status: "disabled", exportFailures: 0 };
270
+ }
253
271
  getTracer() {
254
272
  const provider = this.provider ?? api_1.trace.getTracerProvider();
255
273
  return provider.getTracer(span_filter_js_1.ATLAN_SDK_SCOPE, version_js_1.SDK_VERSION);
@@ -338,14 +356,20 @@ class AtlanAI {
338
356
  return result;
339
357
  }
340
358
  /** Force the processor pipeline to export (SPEC §10.3). */
341
- flush() {
359
+ async flush() {
342
360
  if (this.spanProcessor === null)
343
361
  return Promise.resolve();
344
- const flushing = this.spanProcessor.forceFlush().catch(() => {
345
- logger_js_1.logger.debug("flush failed");
346
- });
362
+ const flushing = this.spanProcessor.forceFlush();
347
363
  this.waitUntil?.(flushing);
348
- return flushing;
364
+ try {
365
+ await flushing;
366
+ }
367
+ catch {
368
+ throw new Error("Atlan trace export failed; inspect client.exportHealth and retry");
369
+ }
370
+ if (this.exportHealth.status === "failed") {
371
+ throw new Error("Atlan trace export failed; inspect client.exportHealth and retry");
372
+ }
349
373
  }
350
374
  async shutdown() {
351
375
  if (this.shutdownDone || this.provider === null)
@@ -362,7 +386,7 @@ class AtlanAI {
362
386
  }
363
387
  exports.AtlanAI = AtlanAI;
364
388
  /**
365
- * Initialize the SDK. Idempotent per API key (SPEC §10.2). Throws
389
+ * Initialize the SDK. Idempotent per pipeline identity (SPEC §10.2). Throws
366
390
  * AtlanConfigError only when an Atlan endpoint is configured without a
367
391
  * workspace (SPEC §2.4); all other misconfiguration logs a warning and returns
368
392
  * a disabled, no-op client.
@@ -379,7 +403,7 @@ function init(options = {}) {
379
403
  config = (0, config_js_1.resolveConfig)({ ...options, tracingEnabled: false });
380
404
  }
381
405
  (0, logger_js_1.setDebug)(config.debug);
382
- const key = clientKey(config.apiKey);
406
+ const key = clientKey(config);
383
407
  const bucket = registry();
384
408
  const existing = bucket.clients.get(key);
385
409
  if (existing) {
@@ -398,8 +422,11 @@ function init(options = {}) {
398
422
  */
399
423
  function getClient(apiKey) {
400
424
  const bucket = registry();
401
- const key = apiKey !== undefined ? clientKey(apiKey) : bucket.defaultKey;
402
- const existing = key !== undefined ? bucket.clients.get(key) : undefined;
425
+ const existing = apiKey === undefined
426
+ ? bucket.defaultKey === undefined
427
+ ? undefined
428
+ : bucket.clients.get(bucket.defaultKey)
429
+ : [...bucket.clients.values()].find((client) => client.config.apiKey === apiKey);
403
430
  if (existing)
404
431
  return existing;
405
432
  return new AtlanAI((0, config_js_1.resolveConfig)({ tracingEnabled: false }));
@@ -7,7 +7,7 @@
7
7
  * (SPEC §2.4). On runtimes without ambient env (workerd), everything resolves
8
8
  * from the init options alone.
9
9
  */
10
- export declare const DEFAULT_BASE_URL = "https://agentgateway.atlan.engineering";
10
+ export declare const DEFAULT_BASE_URL = "https://api.atlan.com";
11
11
  /**
12
12
  * Modes (SPEC §3.3): "atlan" exports to the gateway with Atlan headers; "otlp"
13
13
  * is generic-collector mode driven purely by OTEL_EXPORTER_OTLP_* env;
@@ -42,6 +42,8 @@ export interface ConfigOptions {
42
42
  tracingEnabled?: boolean;
43
43
  traceContent?: boolean;
44
44
  sampleRate?: number;
45
+ /** Export and flush timeout in seconds. Defaults to ATLAN_TIMEOUT or 30. */
46
+ timeoutS?: number;
45
47
  }
46
48
  export declare function validAtlanBaseUrl(baseUrl: string): boolean;
47
49
  /**
@@ -14,7 +14,7 @@ exports.validAtlanBaseUrl = validAtlanBaseUrl;
14
14
  exports.resolveConfig = resolveConfig;
15
15
  const isomorph_js_1 = require("./isomorph.js");
16
16
  const logger_js_1 = require("./logger.js");
17
- exports.DEFAULT_BASE_URL = "https://agentgateway.atlan.engineering";
17
+ exports.DEFAULT_BASE_URL = "https://api.atlan.com";
18
18
  const LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1", "[::1]"]);
19
19
  /** Thrown only for the spec-mandated fail-fast cases (SPEC §2.4). */
20
20
  class AtlanConfigError extends Error {
@@ -69,6 +69,11 @@ function resolveConfig(options = {}) {
69
69
  logger_js_1.logger.warn(`sample_rate ${rate} outside [0, 1]; using 1.0`);
70
70
  rate = 1.0;
71
71
  }
72
+ let timeout = options.timeoutS ?? envNumber("ATLAN_TIMEOUT", 30.0);
73
+ if (!Number.isFinite(timeout) || timeout <= 0) {
74
+ logger_js_1.logger.warn(`timeoutS ${timeout} must be positive and finite; using 30`);
75
+ timeout = 30.0;
76
+ }
72
77
  let mode = "disabled";
73
78
  if (enabled) {
74
79
  if (apiKey) {
@@ -107,7 +112,7 @@ function resolveConfig(options = {}) {
107
112
  sampleRate: rate,
108
113
  flushAt: envNumber("ATLAN_FLUSH_AT", 64, true),
109
114
  flushIntervalS: envNumber("ATLAN_FLUSH_INTERVAL", 5.0),
110
- timeoutS: envNumber("ATLAN_TIMEOUT", 30.0),
115
+ timeoutS: timeout,
111
116
  maxPayloadBytes: envNumber("ATLAN_MAX_PAYLOAD_BYTES", 1024 * 1024, true),
112
117
  debug: envBool("ATLAN_DEBUG", false),
113
118
  };
@@ -8,7 +8,8 @@
8
8
  * standard OTEL_EXPORTER_OTLP_(TRACES_)ENDPOINT / _HEADERS env chain — the SDK
9
9
  * adds no Atlan headers there.
10
10
  */
11
- import type { SpanExporter } from "@opentelemetry/sdk-trace-base";
11
+ import { type ExportResult } from "@opentelemetry/core";
12
+ import type { ReadableSpan, SpanExporter } from "@opentelemetry/sdk-trace-base";
12
13
  import type { ResolvedConfig } from "./config.js";
13
14
  /**
14
15
  * Lazy OTLP exporter: the heavyweight node-only OTLP/protobuf chain is
@@ -18,3 +19,20 @@ import type { ResolvedConfig } from "./config.js";
18
19
  * worker bundles.
19
20
  */
20
21
  export declare function buildExporter(config: ResolvedConfig): SpanExporter;
22
+ export interface ExportHealth {
23
+ status: "ok" | "failed";
24
+ exportFailures: number;
25
+ lastError?: string;
26
+ }
27
+ /** Makes asynchronous exporter failures observable to `flush()` callers. */
28
+ export declare class TrackingSpanExporter implements SpanExporter {
29
+ private readonly wrapped;
30
+ private failures;
31
+ private lastError;
32
+ constructor(wrapped: SpanExporter);
33
+ get health(): ExportHealth;
34
+ private failed;
35
+ export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void;
36
+ shutdown(): Promise<void>;
37
+ forceFlush(): Promise<void>;
38
+ }
@@ -10,7 +10,9 @@
10
10
  * adds no Atlan headers there.
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.TrackingSpanExporter = void 0;
13
14
  exports.buildExporter = buildExporter;
15
+ const core_1 = require("@opentelemetry/core");
14
16
  const logger_js_1 = require("./logger.js");
15
17
  const version_js_1 = require("./version.js");
16
18
  async function loadOtlpExporter(config) {
@@ -44,29 +46,69 @@ async function loadOtlpExporter(config) {
44
46
  function buildExporter(config) {
45
47
  let loading = null;
46
48
  const load = () => {
47
- loading ??= loadOtlpExporter(config).catch(() => {
48
- logger_js_1.logger.warn("OTLP exporter unavailable on this runtime; spans will be dropped");
49
- return null;
50
- });
49
+ loading ??= loadOtlpExporter(config);
51
50
  return loading;
52
51
  };
53
52
  return {
54
53
  export(spans, resultCallback) {
55
- void load().then((exporter) => {
56
- if (exporter === null) {
57
- resultCallback({ code: 0 });
58
- return;
59
- }
60
- exporter.export(spans, resultCallback);
54
+ void load().then((exporter) => exporter.export(spans, resultCallback), () => {
55
+ logger_js_1.logger.warn("OTLP exporter unavailable on this runtime; trace export failed");
56
+ resultCallback({ code: core_1.ExportResultCode.FAILED });
61
57
  });
62
58
  },
63
59
  async shutdown() {
64
- const exporter = loading === null ? null : await loading;
65
- await exporter?.shutdown();
60
+ if (loading !== null)
61
+ await (await loading).shutdown();
66
62
  },
67
63
  async forceFlush() {
68
- const exporter = loading === null ? null : await loading;
69
- await exporter?.forceFlush?.();
64
+ if (loading !== null)
65
+ await (await loading).forceFlush?.();
70
66
  },
71
67
  };
72
68
  }
69
+ /** Makes asynchronous exporter failures observable to `flush()` callers. */
70
+ class TrackingSpanExporter {
71
+ wrapped;
72
+ failures = 0;
73
+ lastError;
74
+ constructor(wrapped) {
75
+ this.wrapped = wrapped;
76
+ }
77
+ get health() {
78
+ return {
79
+ status: this.failures === 0 ? "ok" : "failed",
80
+ exportFailures: this.failures,
81
+ ...(this.lastError === undefined ? {} : { lastError: this.lastError }),
82
+ };
83
+ }
84
+ failed(detail) {
85
+ this.failures += 1;
86
+ this.lastError = detail;
87
+ }
88
+ export(spans, resultCallback) {
89
+ try {
90
+ this.wrapped.export(spans, (result) => {
91
+ if (result.code !== core_1.ExportResultCode.SUCCESS)
92
+ this.failed("exporter returned failure");
93
+ resultCallback(result);
94
+ });
95
+ }
96
+ catch (error) {
97
+ this.failed(error instanceof Error ? error.name : "exporter threw");
98
+ resultCallback({ code: core_1.ExportResultCode.FAILED });
99
+ }
100
+ }
101
+ shutdown() {
102
+ return this.wrapped.shutdown();
103
+ }
104
+ async forceFlush() {
105
+ try {
106
+ await this.wrapped.forceFlush?.();
107
+ }
108
+ catch (error) {
109
+ this.failed(error instanceof Error ? error.name : "forceFlush failed");
110
+ throw error;
111
+ }
112
+ }
113
+ }
114
+ exports.TrackingSpanExporter = TrackingSpanExporter;
@@ -18,6 +18,8 @@ export interface PropagateAttributesOptions {
18
18
  userId?: string;
19
19
  visitorId?: string;
20
20
  experimentId?: string;
21
+ caseId?: string;
22
+ datasetRecordId?: string;
21
23
  tags?: readonly string[];
22
24
  metadata?: Record<string, unknown>;
23
25
  traceName?: string;
@@ -57,6 +57,8 @@ const SESSION_ID_KEY = (0, api_1.createContextKey)("atlan.propagated.session_id"
57
57
  const USER_ID_KEY = (0, api_1.createContextKey)("atlan.propagated.user_id");
58
58
  const VISITOR_ID_KEY = (0, api_1.createContextKey)("atlan.propagated.visitor_id");
59
59
  const EXPERIMENT_ID_KEY = (0, api_1.createContextKey)("atlan.propagated.experiment_id");
60
+ const EVAL_CASE_ID_KEY = (0, api_1.createContextKey)("atlan.propagated.eval_case_id");
61
+ const DATASET_RECORD_ID_KEY = (0, api_1.createContextKey)("atlan.propagated.dataset_record_id");
60
62
  const TAGS_KEY = (0, api_1.createContextKey)("atlan.propagated.tags");
61
63
  const METADATA_KEY = (0, api_1.createContextKey)("atlan.propagated.metadata");
62
64
  const TRACE_NAME_KEY = (0, api_1.createContextKey)("atlan.propagated.trace_name");
@@ -127,6 +129,13 @@ function propagatedAttributesFromContext(context, includeContent = true) {
127
129
  const experimentId = context.getValue(EXPERIMENT_ID_KEY);
128
130
  if (typeof experimentId === "string")
129
131
  attributes[sc.ATLAN_EVAL_EXPERIMENT_ID] = experimentId;
132
+ const caseId = context.getValue(EVAL_CASE_ID_KEY);
133
+ if (typeof caseId === "string")
134
+ attributes[sc.ATLAN_EVAL_CASE_ID] = caseId;
135
+ const datasetRecordId = context.getValue(DATASET_RECORD_ID_KEY);
136
+ if (typeof datasetRecordId === "string") {
137
+ attributes[sc.ATLAN_EVAL_DATASET_RECORD_ID] = datasetRecordId;
138
+ }
130
139
  const tags = context.getValue(TAGS_KEY);
131
140
  if (Array.isArray(tags) && tags.length > 0)
132
141
  attributes[sc.ATLAN_TAGS] = [...tags];
@@ -156,6 +165,13 @@ function propagateAttributes(options, fn) {
156
165
  const experimentId = validShortString("experimentId", options.experimentId);
157
166
  if (experimentId !== undefined)
158
167
  context = context.setValue(EXPERIMENT_ID_KEY, experimentId);
168
+ const caseId = validShortString("caseId", options.caseId);
169
+ if (caseId !== undefined)
170
+ context = context.setValue(EVAL_CASE_ID_KEY, caseId);
171
+ const datasetRecordId = validShortString("datasetRecordId", options.datasetRecordId);
172
+ if (datasetRecordId !== undefined) {
173
+ context = context.setValue(DATASET_RECORD_ID_KEY, datasetRecordId);
174
+ }
159
175
  const newTags = validTags(options.tags);
160
176
  if (newTags.length > 0) {
161
177
  const existing = context.getValue(TAGS_KEY);
@@ -9,6 +9,10 @@ export type ScoreDataType = (typeof SCORE_DATA_TYPES)[number];
9
9
  export declare const ATLAN_COMPLETION_START_TIME = "atlan.completion_start_time";
10
10
  export declare const ATLAN_CONSENT_STORE_CONTENT = "atlan.consent.store_content";
11
11
  export declare const ATLAN_ENVIRONMENT = "atlan.environment";
12
+ export declare const ATLAN_EVAL_CASE_ID = "atlan.eval.case_id";
13
+ export declare const ATLAN_EVAL_DATASET_RECORD_ID = "atlan.eval.dataset_record_id";
14
+ export declare const ATLAN_EVAL_EVIDENCE_COMPLETE = "atlan.eval.evidence_complete";
15
+ export declare const ATLAN_EVAL_EVIDENCE_TRUNCATED = "atlan.eval.evidence_truncated";
12
16
  export declare const ATLAN_EVAL_EXPERIMENT_ID = "atlan.eval.experiment_id";
13
17
  export declare const ATLAN_INPUT = "atlan.input";
14
18
  export declare const ATLAN_INTERNAL_AS_ROOT = "atlan.internal.as_root";