@sogni-ai/sogni-client 5.2.0 → 5.3.0
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/CHANGELOG.md +8 -0
- package/README.md +37 -0
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.d.ts +2 -1
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js +2 -2
- package/dist/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js.map +1 -1
- package/dist/ApiClient/WebSocketClient/index.d.ts +3 -1
- package/dist/ApiClient/WebSocketClient/index.js +4 -1
- package/dist/ApiClient/WebSocketClient/index.js.map +1 -1
- package/dist/ApiClient/index.d.ts +10 -1
- package/dist/ApiClient/index.js +16 -3
- package/dist/ApiClient/index.js.map +1 -1
- package/dist/ApiGroup.d.ts +3 -0
- package/dist/ApiGroup.js +13 -0
- package/dist/ApiGroup.js.map +1 -1
- package/dist/Chat/ChatTools.js +2 -1
- package/dist/Chat/ChatTools.js.map +1 -1
- package/dist/Chat/index.d.ts +6 -0
- package/dist/Chat/index.js +35 -8
- package/dist/Chat/index.js.map +1 -1
- package/dist/Chat/types.d.ts +10 -1
- package/dist/CreativeWorkflows/index.js +4 -5
- package/dist/CreativeWorkflows/index.js.map +1 -1
- package/dist/CreativeWorkflows/types.d.ts +7 -0
- package/dist/Projects/createJobRequestMessage.js +3 -1
- package/dist/Projects/createJobRequestMessage.js.map +1 -1
- package/dist/Projects/index.js +1 -1
- package/dist/Projects/index.js.map +1 -1
- package/dist/Projects/types/index.d.ts +6 -0
- package/dist/Projects/types/index.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/RestClient.d.ts +3 -2
- package/dist/lib/RestClient.js +2 -3
- package/dist/lib/RestClient.js.map +1 -1
- package/dist/lib/attribution.d.ts +24 -0
- package/dist/lib/attribution.js +264 -0
- package/dist/lib/attribution.js.map +1 -0
- package/dist/types/attribution.d.ts +67 -0
- package/dist/types/attribution.js +3 -0
- package/dist/types/attribution.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist-esm/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js +2 -2
- package/dist-esm/ApiClient/WebSocketClient/BrowserWebSocketClient/index.js.map +1 -1
- package/dist-esm/ApiClient/WebSocketClient/index.js +4 -1
- package/dist-esm/ApiClient/WebSocketClient/index.js.map +1 -1
- package/dist-esm/ApiClient/index.js +16 -3
- package/dist-esm/ApiClient/index.js.map +1 -1
- package/dist-esm/ApiGroup.js +13 -0
- package/dist-esm/ApiGroup.js.map +1 -1
- package/dist-esm/Chat/ChatTools.js +2 -1
- package/dist-esm/Chat/ChatTools.js.map +1 -1
- package/dist-esm/Chat/index.js +35 -8
- package/dist-esm/Chat/index.js.map +1 -1
- package/dist-esm/CreativeWorkflows/index.js +4 -5
- package/dist-esm/CreativeWorkflows/index.js.map +1 -1
- package/dist-esm/Projects/createJobRequestMessage.js +3 -1
- package/dist-esm/Projects/createJobRequestMessage.js.map +1 -1
- package/dist-esm/Projects/index.js +1 -1
- package/dist-esm/Projects/index.js.map +1 -1
- package/dist-esm/Projects/types/index.js.map +1 -1
- package/dist-esm/index.js +1 -0
- package/dist-esm/index.js.map +1 -1
- package/dist-esm/lib/RestClient.js +2 -3
- package/dist-esm/lib/RestClient.js.map +1 -1
- package/dist-esm/lib/attribution.js +257 -0
- package/dist-esm/lib/attribution.js.map +1 -0
- package/dist-esm/types/attribution.js +2 -0
- package/dist-esm/types/attribution.js.map +1 -0
- package/dist-esm/version.js +1 -1
- package/llms-full.txt +27 -0
- package/llms.txt +4 -0
- package/package.json +2 -1
- package/src/ApiClient/WebSocketClient/BrowserWebSocketClient/index.ts +5 -2
- package/src/ApiClient/WebSocketClient/index.ts +10 -1
- package/src/ApiClient/index.ts +42 -2
- package/src/ApiGroup.ts +25 -0
- package/src/Chat/ChatTools.ts +5 -1
- package/src/Chat/index.ts +46 -7
- package/src/Chat/types.ts +10 -1
- package/src/CreativeWorkflows/index.ts +11 -3
- package/src/CreativeWorkflows/types.ts +7 -0
- package/src/Projects/createJobRequestMessage.ts +4 -1
- package/src/Projects/index.ts +2 -1
- package/src/Projects/types/index.ts +6 -0
- package/src/index.ts +35 -1
- package/src/lib/RestClient.ts +10 -3
- package/src/lib/attribution.ts +304 -0
- package/src/types/attribution.ts +89 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AgentAttributionMetadata,
|
|
3
|
+
AgentSurface,
|
|
4
|
+
ConnectionAttribution,
|
|
5
|
+
ExecutionMode,
|
|
6
|
+
InteractionKind,
|
|
7
|
+
OperationScope,
|
|
8
|
+
WorkloadAttributionDefaults,
|
|
9
|
+
WorkloadAttributionInput,
|
|
10
|
+
WorkloadKind
|
|
11
|
+
} from '../types/attribution.js';
|
|
12
|
+
|
|
13
|
+
const MAX_METADATA_LENGTH = 128;
|
|
14
|
+
const MAX_VERSION_LENGTH = 32;
|
|
15
|
+
const MAX_OPERATION_ID_LENGTH = 128;
|
|
16
|
+
const UNSAFE_HEADER_CHARACTER = /[\u0000-\u001f\u007f]/;
|
|
17
|
+
const VERSION_PATTERN = /^[0-9][0-9A-Za-z.+_-]*$/;
|
|
18
|
+
const OPERATION_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]*$/;
|
|
19
|
+
|
|
20
|
+
const INTERACTION_KINDS = new Set<InteractionKind>([
|
|
21
|
+
'human_ui',
|
|
22
|
+
'external_agent',
|
|
23
|
+
'service',
|
|
24
|
+
'unknown'
|
|
25
|
+
]);
|
|
26
|
+
const WORKLOAD_KINDS = new Set<WorkloadKind>(['direct', 'agent_mediated', 'service', 'unknown']);
|
|
27
|
+
const OPERATION_SCOPES = new Set<OperationScope>(['top_level', 'child', 'unknown']);
|
|
28
|
+
const AGENT_SURFACES = new Set<AgentSurface>([
|
|
29
|
+
'native_web',
|
|
30
|
+
'native_mobile',
|
|
31
|
+
'native_desktop',
|
|
32
|
+
'plugin',
|
|
33
|
+
'personal_skill',
|
|
34
|
+
'mcp',
|
|
35
|
+
'cli',
|
|
36
|
+
'sdk',
|
|
37
|
+
'openai_compatible',
|
|
38
|
+
'direct_api',
|
|
39
|
+
'unknown'
|
|
40
|
+
]);
|
|
41
|
+
const EXECUTION_MODES = new Set<ExecutionMode>(['browser', 'durable', 'server', 'unknown']);
|
|
42
|
+
|
|
43
|
+
export type NormalizedConnectionAttribution = Partial<ConnectionAttribution>;
|
|
44
|
+
export type NormalizedWorkloadAttribution = WorkloadAttributionInput;
|
|
45
|
+
|
|
46
|
+
function normalizeEnum<T extends string>(value: unknown, allowed: ReadonlySet<T>): T | undefined {
|
|
47
|
+
if (typeof value !== 'string') return undefined;
|
|
48
|
+
const normalized = value.trim();
|
|
49
|
+
return allowed.has(normalized as T) ? (normalized as T) : undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function normalizeBoundedString(value: unknown, maxLength: number): string | undefined {
|
|
53
|
+
if (typeof value !== 'string') return undefined;
|
|
54
|
+
const normalized = value.trim();
|
|
55
|
+
if (
|
|
56
|
+
normalized.length === 0 ||
|
|
57
|
+
normalized.length > maxLength ||
|
|
58
|
+
UNSAFE_HEADER_CHARACTER.test(normalized)
|
|
59
|
+
) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
return normalized;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function normalizeVersion(value: unknown): string | undefined {
|
|
66
|
+
const normalized = normalizeBoundedString(value, MAX_VERSION_LENGTH);
|
|
67
|
+
return normalized && VERSION_PATTERN.test(normalized) ? normalized : undefined;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function normalizeOperationId(value: unknown): string | undefined {
|
|
71
|
+
if (
|
|
72
|
+
typeof value !== 'string' ||
|
|
73
|
+
value.length === 0 ||
|
|
74
|
+
value.length > MAX_OPERATION_ID_LENGTH ||
|
|
75
|
+
value.trim() !== value ||
|
|
76
|
+
UNSAFE_HEADER_CHARACTER.test(value) ||
|
|
77
|
+
!OPERATION_ID_PATTERN.test(value)
|
|
78
|
+
) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function normalizeAgentMetadata(
|
|
85
|
+
input: AgentAttributionMetadata | Record<string, unknown> | undefined
|
|
86
|
+
): AgentAttributionMetadata {
|
|
87
|
+
if (!input || typeof input !== 'object') return {};
|
|
88
|
+
const result: AgentAttributionMetadata = {};
|
|
89
|
+
const agentFramework = normalizeBoundedString(input.agentFramework, MAX_METADATA_LENGTH);
|
|
90
|
+
const agentFrameworkVersion = normalizeVersion(input.agentFrameworkVersion);
|
|
91
|
+
const agentSurface = normalizeEnum(input.agentSurface, AGENT_SURFACES);
|
|
92
|
+
const agentSurfaceVersion = normalizeVersion(input.agentSurfaceVersion);
|
|
93
|
+
const executionMode = normalizeEnum(input.executionMode, EXECUTION_MODES);
|
|
94
|
+
|
|
95
|
+
if (agentFramework) result.agentFramework = agentFramework;
|
|
96
|
+
if (agentFrameworkVersion) result.agentFrameworkVersion = agentFrameworkVersion;
|
|
97
|
+
if (agentSurface) result.agentSurface = agentSurface;
|
|
98
|
+
if (agentSurfaceVersion) result.agentSurfaceVersion = agentSurfaceVersion;
|
|
99
|
+
if (executionMode) result.executionMode = executionMode;
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function mergeDefined(defaults: object | undefined, overrides: object | undefined) {
|
|
104
|
+
const merged: Record<string, unknown> = { ...(defaults ?? {}) };
|
|
105
|
+
if (overrides && typeof overrides === 'object') {
|
|
106
|
+
const defaultValues = (defaults ?? {}) as Record<string, unknown>;
|
|
107
|
+
const overrideValues = overrides as Record<string, unknown>;
|
|
108
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
109
|
+
if (value !== undefined) merged[key] = value;
|
|
110
|
+
}
|
|
111
|
+
// A version belongs to its framework/surface. Do not accidentally retain
|
|
112
|
+
// one default's version when a request changes the corresponding identity.
|
|
113
|
+
if (
|
|
114
|
+
overrideValues.agentFramework !== undefined &&
|
|
115
|
+
overrideValues.agentFramework !== defaultValues.agentFramework &&
|
|
116
|
+
overrideValues.agentFrameworkVersion === undefined
|
|
117
|
+
) {
|
|
118
|
+
delete merged.agentFrameworkVersion;
|
|
119
|
+
}
|
|
120
|
+
if (
|
|
121
|
+
overrideValues.agentSurface !== undefined &&
|
|
122
|
+
overrideValues.agentSurface !== defaultValues.agentSurface &&
|
|
123
|
+
overrideValues.agentSurfaceVersion === undefined
|
|
124
|
+
) {
|
|
125
|
+
delete merged.agentSurfaceVersion;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return merged;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function hasValues(value: object): boolean {
|
|
132
|
+
return Object.keys(value).length > 0;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function normalizeConnectionAttribution(
|
|
136
|
+
input: ConnectionAttribution | Partial<ConnectionAttribution> | undefined
|
|
137
|
+
): NormalizedConnectionAttribution | undefined {
|
|
138
|
+
if (!input || typeof input !== 'object') return undefined;
|
|
139
|
+
const result: NormalizedConnectionAttribution = normalizeAgentMetadata(input);
|
|
140
|
+
const interactionKind = normalizeEnum(
|
|
141
|
+
(input as unknown as Record<string, unknown>).interactionKind,
|
|
142
|
+
INTERACTION_KINDS
|
|
143
|
+
);
|
|
144
|
+
if (interactionKind) result.interactionKind = interactionKind;
|
|
145
|
+
return hasValues(result) ? result : undefined;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Merge immutable client defaults with one operation's overrides and add
|
|
150
|
+
* lineage derived from the underlying request ID. Invalid runtime values are
|
|
151
|
+
* dropped instead of rejecting an otherwise valid inference request.
|
|
152
|
+
*/
|
|
153
|
+
export function resolveWorkloadAttribution(
|
|
154
|
+
defaults: WorkloadAttributionDefaults | undefined,
|
|
155
|
+
overrides: WorkloadAttributionInput | undefined,
|
|
156
|
+
fallbackOperationId?: string
|
|
157
|
+
): NormalizedWorkloadAttribution | undefined {
|
|
158
|
+
if (!defaults && !overrides) return undefined;
|
|
159
|
+
|
|
160
|
+
const merged = mergeDefined(defaults, overrides);
|
|
161
|
+
const result: NormalizedWorkloadAttribution = normalizeAgentMetadata(merged);
|
|
162
|
+
const workloadKind = normalizeEnum(merged.workloadKind, WORKLOAD_KINDS);
|
|
163
|
+
const operationScope = normalizeEnum(merged.operationScope, OPERATION_SCOPES);
|
|
164
|
+
const operationId = normalizeOperationId(merged.operationId);
|
|
165
|
+
const rootOperationId = normalizeOperationId(merged.rootOperationId);
|
|
166
|
+
const parentOperationId = normalizeOperationId(merged.parentOperationId);
|
|
167
|
+
|
|
168
|
+
if (workloadKind) result.workloadKind = workloadKind;
|
|
169
|
+
if (operationScope) result.operationScope = operationScope;
|
|
170
|
+
if (operationId) result.operationId = operationId;
|
|
171
|
+
if (rootOperationId) result.rootOperationId = rootOperationId;
|
|
172
|
+
if (parentOperationId) result.parentOperationId = parentOperationId;
|
|
173
|
+
|
|
174
|
+
if (result.workloadKind && result.workloadKind !== 'agent_mediated') {
|
|
175
|
+
delete result.agentFramework;
|
|
176
|
+
delete result.agentFrameworkVersion;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Do not turn an empty/invalid attribution object into attributed traffic
|
|
180
|
+
// solely because the transport happens to have a request ID.
|
|
181
|
+
if (!hasValues(result)) return undefined;
|
|
182
|
+
|
|
183
|
+
if (!result.operationId) {
|
|
184
|
+
const fallback = normalizeOperationId(fallbackOperationId);
|
|
185
|
+
if (fallback) result.operationId = fallback;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (result.operationId && !result.operationScope) {
|
|
189
|
+
result.operationScope =
|
|
190
|
+
result.parentOperationId ||
|
|
191
|
+
(result.rootOperationId && result.rootOperationId !== result.operationId)
|
|
192
|
+
? 'child'
|
|
193
|
+
: 'top_level';
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (result.operationScope === 'child' && result.rootOperationId && !result.parentOperationId) {
|
|
197
|
+
result.parentOperationId = result.rootOperationId;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (result.operationScope === 'top_level' && result.operationId) {
|
|
201
|
+
result.rootOperationId = result.operationId;
|
|
202
|
+
delete result.parentOperationId;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** Add flat camelCase connection attribution fields to a WebSocket URL. */
|
|
209
|
+
export function appendConnectionAttributionQuery(
|
|
210
|
+
url: URL,
|
|
211
|
+
attribution: NormalizedConnectionAttribution | undefined
|
|
212
|
+
): void {
|
|
213
|
+
if (!attribution) return;
|
|
214
|
+
const fields: Array<keyof NormalizedConnectionAttribution> = [
|
|
215
|
+
'interactionKind',
|
|
216
|
+
'agentFramework',
|
|
217
|
+
'agentFrameworkVersion',
|
|
218
|
+
'agentSurface',
|
|
219
|
+
'agentSurfaceVersion',
|
|
220
|
+
'executionMode'
|
|
221
|
+
];
|
|
222
|
+
for (const field of fields) {
|
|
223
|
+
const value = attribution[field];
|
|
224
|
+
if (typeof value === 'string') url.searchParams.set(field, value);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** Return flat camelCase workload fields for socket request payloads. */
|
|
229
|
+
export function workloadAttributionToWireFields(
|
|
230
|
+
attribution: NormalizedWorkloadAttribution | undefined
|
|
231
|
+
): Record<string, string> {
|
|
232
|
+
if (!attribution) return {};
|
|
233
|
+
const result: Record<string, string> = {};
|
|
234
|
+
for (const field of [
|
|
235
|
+
'workloadKind',
|
|
236
|
+
'agentFramework',
|
|
237
|
+
'agentFrameworkVersion',
|
|
238
|
+
'agentSurface',
|
|
239
|
+
'agentSurfaceVersion',
|
|
240
|
+
'executionMode',
|
|
241
|
+
'operationScope',
|
|
242
|
+
'operationId',
|
|
243
|
+
'rootOperationId',
|
|
244
|
+
'parentOperationId'
|
|
245
|
+
] as const) {
|
|
246
|
+
const value = attribution[field];
|
|
247
|
+
if (typeof value === 'string') result[field] = value;
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export interface SogniAttributionHeaderInput {
|
|
253
|
+
appSource?: string;
|
|
254
|
+
connection?: NormalizedConnectionAttribution;
|
|
255
|
+
workload?: NormalizedWorkloadAttribution;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Build headers only for requests whose caller has already established that
|
|
260
|
+
* the destination is a Sogni-owned endpoint.
|
|
261
|
+
*/
|
|
262
|
+
export function buildSogniAttributionHeaders({
|
|
263
|
+
appSource,
|
|
264
|
+
connection,
|
|
265
|
+
workload
|
|
266
|
+
}: SogniAttributionHeaderInput): Record<string, string> {
|
|
267
|
+
const headers: Record<string, string> = {};
|
|
268
|
+
const normalizedAppSource = normalizeBoundedString(appSource, MAX_METADATA_LENGTH);
|
|
269
|
+
if (normalizedAppSource) headers['X-App-Source'] = normalizedAppSource;
|
|
270
|
+
if (connection?.interactionKind) {
|
|
271
|
+
headers['X-Sogni-Interaction-Kind'] = connection.interactionKind;
|
|
272
|
+
}
|
|
273
|
+
if (workload?.workloadKind) {
|
|
274
|
+
headers['X-Sogni-Workload-Kind'] = workload.workloadKind;
|
|
275
|
+
}
|
|
276
|
+
if (workload?.agentFramework) {
|
|
277
|
+
headers['X-Sogni-Agent-Framework'] = workload.agentFramework;
|
|
278
|
+
}
|
|
279
|
+
if (workload?.agentFrameworkVersion) {
|
|
280
|
+
headers['X-Sogni-Agent-Framework-Version'] = workload.agentFrameworkVersion;
|
|
281
|
+
}
|
|
282
|
+
if (workload?.agentSurface) {
|
|
283
|
+
headers['X-Sogni-Agent-Surface'] = workload.agentSurface;
|
|
284
|
+
}
|
|
285
|
+
if (workload?.agentSurfaceVersion) {
|
|
286
|
+
headers['X-Sogni-Agent-Surface-Version'] = workload.agentSurfaceVersion;
|
|
287
|
+
}
|
|
288
|
+
if (workload?.executionMode) {
|
|
289
|
+
headers['X-Sogni-Execution-Mode'] = workload.executionMode;
|
|
290
|
+
}
|
|
291
|
+
if (workload?.operationScope) {
|
|
292
|
+
headers['X-Sogni-Operation-Scope'] = workload.operationScope;
|
|
293
|
+
}
|
|
294
|
+
if (workload?.operationId) {
|
|
295
|
+
headers['X-Sogni-Operation-Id'] = workload.operationId;
|
|
296
|
+
}
|
|
297
|
+
if (workload?.rootOperationId) {
|
|
298
|
+
headers['X-Sogni-Root-Operation-Id'] = workload.rootOperationId;
|
|
299
|
+
}
|
|
300
|
+
if (workload?.parentOperationId) {
|
|
301
|
+
headers['X-Sogni-Parent-Operation-Id'] = workload.parentOperationId;
|
|
302
|
+
}
|
|
303
|
+
return headers;
|
|
304
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a caller is interacting with Sogni at the connection boundary.
|
|
3
|
+
*
|
|
4
|
+
* Connection attribution and workload attribution are intentionally separate:
|
|
5
|
+
* a human-facing application can issue both direct and agent-mediated work on
|
|
6
|
+
* the same connection.
|
|
7
|
+
*/
|
|
8
|
+
export type InteractionKind = 'human_ui' | 'external_agent' | 'service' | 'unknown';
|
|
9
|
+
|
|
10
|
+
/** How a logical Sogni workload was initiated. */
|
|
11
|
+
export type WorkloadKind = 'direct' | 'agent_mediated' | 'service' | 'unknown';
|
|
12
|
+
|
|
13
|
+
/** Whether an operation is a user-visible root or work performed on its behalf. */
|
|
14
|
+
export type OperationScope = 'top_level' | 'child' | 'unknown';
|
|
15
|
+
|
|
16
|
+
/** The integration surface used to reach Sogni. */
|
|
17
|
+
export type AgentSurface =
|
|
18
|
+
| 'native_web'
|
|
19
|
+
| 'native_mobile'
|
|
20
|
+
| 'native_desktop'
|
|
21
|
+
| 'plugin'
|
|
22
|
+
| 'personal_skill'
|
|
23
|
+
| 'mcp'
|
|
24
|
+
| 'cli'
|
|
25
|
+
| 'sdk'
|
|
26
|
+
| 'openai_compatible'
|
|
27
|
+
| 'direct_api'
|
|
28
|
+
| 'unknown';
|
|
29
|
+
|
|
30
|
+
/** Optional execution detail for agent-mediated products. */
|
|
31
|
+
export type ExecutionMode = 'browser' | 'durable' | 'server' | 'unknown';
|
|
32
|
+
|
|
33
|
+
/** Agent metadata shared by connection and workload attribution. */
|
|
34
|
+
export interface AgentAttributionMetadata {
|
|
35
|
+
/** Canonical agent host, for example `codex`, `claude-code`, or `sogni-chat`. */
|
|
36
|
+
agentFramework?: string;
|
|
37
|
+
/** Version of the agent host when known. */
|
|
38
|
+
agentFrameworkVersion?: string;
|
|
39
|
+
/** How the agent host integrated with Sogni. */
|
|
40
|
+
agentSurface?: AgentSurface;
|
|
41
|
+
/** Version of the integration surface when known. */
|
|
42
|
+
agentSurfaceVersion?: string;
|
|
43
|
+
/** Product execution detail, such as browser or durable execution. */
|
|
44
|
+
executionMode?: ExecutionMode;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Attribution captured when the SDK opens a Sogni WebSocket connection. */
|
|
48
|
+
export interface ConnectionAttribution extends AgentAttributionMetadata {
|
|
49
|
+
interactionKind: InteractionKind;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Defaults applied independently to each attributed workload.
|
|
54
|
+
*
|
|
55
|
+
* Operation IDs do not belong in client-wide defaults because concurrent
|
|
56
|
+
* requests must never share mutable lineage state.
|
|
57
|
+
*/
|
|
58
|
+
export interface WorkloadAttributionDefaults extends AgentAttributionMetadata {
|
|
59
|
+
workloadKind: WorkloadKind;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Opaque identifiers that relate a request to its logical parent and root. */
|
|
63
|
+
export interface OperationLineage {
|
|
64
|
+
operationScope: OperationScope;
|
|
65
|
+
operationId: string;
|
|
66
|
+
rootOperationId: string;
|
|
67
|
+
parentOperationId?: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Per-operation attribution input.
|
|
72
|
+
*
|
|
73
|
+
* Every property is optional so a request can override only one client
|
|
74
|
+
* default. When attribution is present, the SDK supplies an operation ID from
|
|
75
|
+
* the underlying project/job request when one is not provided.
|
|
76
|
+
*/
|
|
77
|
+
export interface WorkloadAttributionInput
|
|
78
|
+
extends Partial<WorkloadAttributionDefaults>, Partial<OperationLineage> {}
|
|
79
|
+
|
|
80
|
+
/** Fully classified workload attribution after server normalization. */
|
|
81
|
+
export interface WorkloadAttribution extends AgentAttributionMetadata, OperationLineage {
|
|
82
|
+
workloadKind: WorkloadKind;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Immutable attribution defaults configured when creating a client. */
|
|
86
|
+
export interface SogniAttributionConfig {
|
|
87
|
+
connection?: ConnectionAttribution;
|
|
88
|
+
workload?: WorkloadAttributionDefaults;
|
|
89
|
+
}
|
package/src/version.ts
CHANGED