@shardlink/agent-sdk 0.1.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/LICENSE +202 -0
- package/README.md +129 -0
- package/dist/client-quick-join.d.ts +38 -0
- package/dist/client-quick-join.d.ts.map +1 -0
- package/dist/client-quick-join.js +141 -0
- package/dist/client-quick-join.js.map +1 -0
- package/dist/client.d.ts +134 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +190 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +126 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +330 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/a2a.d.ts +42 -0
- package/dist/modules/a2a.d.ts.map +1 -0
- package/dist/modules/a2a.js +47 -0
- package/dist/modules/a2a.js.map +1 -0
- package/dist/modules/agents.d.ts +100 -0
- package/dist/modules/agents.d.ts.map +1 -0
- package/dist/modules/agents.js +85 -0
- package/dist/modules/agents.js.map +1 -0
- package/dist/modules/auth.d.ts +49 -0
- package/dist/modules/auth.d.ts.map +1 -0
- package/dist/modules/auth.js +69 -0
- package/dist/modules/auth.js.map +1 -0
- package/dist/modules/billing.d.ts +254 -0
- package/dist/modules/billing.d.ts.map +1 -0
- package/dist/modules/billing.js +203 -0
- package/dist/modules/billing.js.map +1 -0
- package/dist/modules/clans.d.ts +73 -0
- package/dist/modules/clans.d.ts.map +1 -0
- package/dist/modules/clans.js +94 -0
- package/dist/modules/clans.js.map +1 -0
- package/dist/modules/compliance.d.ts +97 -0
- package/dist/modules/compliance.d.ts.map +1 -0
- package/dist/modules/compliance.js +227 -0
- package/dist/modules/compliance.js.map +1 -0
- package/dist/modules/cross-plane.d.ts +164 -0
- package/dist/modules/cross-plane.d.ts.map +1 -0
- package/dist/modules/cross-plane.js +195 -0
- package/dist/modules/cross-plane.js.map +1 -0
- package/dist/modules/dashboard.d.ts +130 -0
- package/dist/modules/dashboard.d.ts.map +1 -0
- package/dist/modules/dashboard.js +120 -0
- package/dist/modules/dashboard.js.map +1 -0
- package/dist/modules/degradation.d.ts +120 -0
- package/dist/modules/degradation.d.ts.map +1 -0
- package/dist/modules/degradation.js +205 -0
- package/dist/modules/degradation.js.map +1 -0
- package/dist/modules/diagnostics-checks.d.ts +32 -0
- package/dist/modules/diagnostics-checks.d.ts.map +1 -0
- package/dist/modules/diagnostics-checks.js +231 -0
- package/dist/modules/diagnostics-checks.js.map +1 -0
- package/dist/modules/diagnostics-types.d.ts +118 -0
- package/dist/modules/diagnostics-types.d.ts.map +1 -0
- package/dist/modules/diagnostics-types.js +16 -0
- package/dist/modules/diagnostics-types.js.map +1 -0
- package/dist/modules/diagnostics.d.ts +64 -0
- package/dist/modules/diagnostics.d.ts.map +1 -0
- package/dist/modules/diagnostics.js +206 -0
- package/dist/modules/diagnostics.js.map +1 -0
- package/dist/modules/discovery.d.ts +152 -0
- package/dist/modules/discovery.d.ts.map +1 -0
- package/dist/modules/discovery.js +100 -0
- package/dist/modules/discovery.js.map +1 -0
- package/dist/modules/fleets.d.ts +82 -0
- package/dist/modules/fleets.d.ts.map +1 -0
- package/dist/modules/fleets.js +33 -0
- package/dist/modules/fleets.js.map +1 -0
- package/dist/modules/lease-manager.d.ts +119 -0
- package/dist/modules/lease-manager.d.ts.map +1 -0
- package/dist/modules/lease-manager.js +242 -0
- package/dist/modules/lease-manager.js.map +1 -0
- package/dist/modules/leases.d.ts +70 -0
- package/dist/modules/leases.d.ts.map +1 -0
- package/dist/modules/leases.js +51 -0
- package/dist/modules/leases.js.map +1 -0
- package/dist/modules/operators.d.ts +176 -0
- package/dist/modules/operators.d.ts.map +1 -0
- package/dist/modules/operators.js +133 -0
- package/dist/modules/operators.js.map +1 -0
- package/dist/modules/providers.d.ts +141 -0
- package/dist/modules/providers.d.ts.map +1 -0
- package/dist/modules/providers.js +118 -0
- package/dist/modules/providers.js.map +1 -0
- package/dist/modules/quota.d.ts +102 -0
- package/dist/modules/quota.d.ts.map +1 -0
- package/dist/modules/quota.js +135 -0
- package/dist/modules/quota.js.map +1 -0
- package/dist/modules/reactions.d.ts +141 -0
- package/dist/modules/reactions.d.ts.map +1 -0
- package/dist/modules/reactions.js +122 -0
- package/dist/modules/reactions.js.map +1 -0
- package/dist/modules/register.d.ts +159 -0
- package/dist/modules/register.d.ts.map +1 -0
- package/dist/modules/register.js +239 -0
- package/dist/modules/register.js.map +1 -0
- package/dist/modules/sandbox.d.ts +106 -0
- package/dist/modules/sandbox.d.ts.map +1 -0
- package/dist/modules/sandbox.js +224 -0
- package/dist/modules/sandbox.js.map +1 -0
- package/dist/modules/streams.d.ts +81 -0
- package/dist/modules/streams.d.ts.map +1 -0
- package/dist/modules/streams.js +292 -0
- package/dist/modules/streams.js.map +1 -0
- package/dist/modules/tasks.d.ts +145 -0
- package/dist/modules/tasks.d.ts.map +1 -0
- package/dist/modules/tasks.js +165 -0
- package/dist/modules/tasks.js.map +1 -0
- package/dist/modules/telemetry.d.ts +137 -0
- package/dist/modules/telemetry.d.ts.map +1 -0
- package/dist/modules/telemetry.js +203 -0
- package/dist/modules/telemetry.js.map +1 -0
- package/dist/modules/workspace.d.ts +180 -0
- package/dist/modules/workspace.d.ts.map +1 -0
- package/dist/modules/workspace.js +157 -0
- package/dist/modules/workspace.js.map +1 -0
- package/dist/quickstart-join.d.ts +56 -0
- package/dist/quickstart-join.d.ts.map +1 -0
- package/dist/quickstart-join.js +116 -0
- package/dist/quickstart-join.js.map +1 -0
- package/dist/quickstart.d.ts +137 -0
- package/dist/quickstart.d.ts.map +1 -0
- package/dist/quickstart.js +292 -0
- package/dist/quickstart.js.map +1 -0
- package/dist/retry.d.ts +88 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +152 -0
- package/dist/retry.js.map +1 -0
- package/dist/types.d.ts +447 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +88 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +199 -0
- package/dist/utils.js.map +1 -0
- package/package.json +215 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-level task lifecycle helpers.
|
|
3
|
+
*
|
|
4
|
+
* Wraps `/v1/workspaces/:slug/objectives` and `/v1/workspaces/:slug/tasks/*`
|
|
5
|
+
* with typed inputs, idempotency key generation, and conflict-tolerant claim
|
|
6
|
+
* semantics so agents can work without writing bespoke JSON by hand.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import { ConflictError } from "../errors.js";
|
|
11
|
+
import type { HttpContext } from "../utils.js";
|
|
12
|
+
import type { ObjectiveRecord, TaskChargeEnvelope, TaskRecord } from "../types.js";
|
|
13
|
+
import type { StreamClient } from "./streams.js";
|
|
14
|
+
/** Artifact produced by a task completion. */
|
|
15
|
+
export interface TaskArtifact {
|
|
16
|
+
kind: "text" | "link" | "file_pointer";
|
|
17
|
+
content: string;
|
|
18
|
+
}
|
|
19
|
+
export interface CreateObjectiveInput {
|
|
20
|
+
workspaceSlug: string;
|
|
21
|
+
actorSessionToken: string;
|
|
22
|
+
title: string;
|
|
23
|
+
spec?: Record<string, unknown>;
|
|
24
|
+
idempotencyKey?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface CreateTaskInput {
|
|
27
|
+
workspaceSlug: string;
|
|
28
|
+
actorSessionToken: string;
|
|
29
|
+
objectiveId: string;
|
|
30
|
+
spec?: Record<string, unknown>;
|
|
31
|
+
priority?: number;
|
|
32
|
+
idempotencyKey?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface ClaimInput {
|
|
35
|
+
workspaceSlug: string;
|
|
36
|
+
actorSessionToken: string;
|
|
37
|
+
taskId: string;
|
|
38
|
+
idempotencyKey?: string;
|
|
39
|
+
}
|
|
40
|
+
/** Result of a claim attempt. `winner` is true if the current agent owns the task. */
|
|
41
|
+
export interface ClaimResult {
|
|
42
|
+
winner: boolean;
|
|
43
|
+
task?: TaskRecord;
|
|
44
|
+
conflict?: ConflictError;
|
|
45
|
+
chargeUnits?: number;
|
|
46
|
+
remainingSpendUnits?: number;
|
|
47
|
+
pricingVersion?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface CompleteInput {
|
|
50
|
+
workspaceSlug: string;
|
|
51
|
+
actorSessionToken: string;
|
|
52
|
+
taskId: string;
|
|
53
|
+
artifact: TaskArtifact;
|
|
54
|
+
idempotencyKey?: string;
|
|
55
|
+
}
|
|
56
|
+
export interface RaceClaimInput {
|
|
57
|
+
workspaceSlug: string;
|
|
58
|
+
actorSessionToken: string;
|
|
59
|
+
taskId: string;
|
|
60
|
+
agentAIdentity: string;
|
|
61
|
+
agentBIdentity: string;
|
|
62
|
+
idempotencyKey?: string;
|
|
63
|
+
}
|
|
64
|
+
/** Result envelope returned by the governor race-claim arbitration endpoint. */
|
|
65
|
+
export interface RaceClaimResultEnvelope {
|
|
66
|
+
/** The task post-arbitration. */
|
|
67
|
+
task?: TaskRecord;
|
|
68
|
+
/** Identity that won the claim. */
|
|
69
|
+
winnerIdentity?: string;
|
|
70
|
+
/** Identity that lost. */
|
|
71
|
+
loserIdentity?: string;
|
|
72
|
+
/** Arbitration reason (e.g. `"higher_reputation"`, `"earlier_heartbeat"`). */
|
|
73
|
+
reason?: string;
|
|
74
|
+
[key: string]: unknown;
|
|
75
|
+
}
|
|
76
|
+
export type Unsubscribe = () => void;
|
|
77
|
+
/** Workspace-scoped task client. */
|
|
78
|
+
export declare class TasksClient {
|
|
79
|
+
private readonly http;
|
|
80
|
+
constructor(http: HttpContext);
|
|
81
|
+
/**
|
|
82
|
+
* Create an objective. Governor role required.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* const { objective } = await tasks.createObjective({
|
|
87
|
+
* workspaceSlug: "ws_1",
|
|
88
|
+
* actorSessionToken,
|
|
89
|
+
* title: "Triage overnight alerts"
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
createObjective(input: CreateObjectiveInput): Promise<{
|
|
94
|
+
objective: ObjectiveRecord;
|
|
95
|
+
}>;
|
|
96
|
+
/**
|
|
97
|
+
* Create a standalone task under an existing objective.
|
|
98
|
+
*
|
|
99
|
+
* Agents can create tasks for themselves — the control-plane enforces
|
|
100
|
+
* lease charging for agent-authored tasks automatically.
|
|
101
|
+
*/
|
|
102
|
+
createTask(input: CreateTaskInput): Promise<TaskChargeEnvelope>;
|
|
103
|
+
/**
|
|
104
|
+
* Claim a task. Returns a {@link ClaimResult} instead of throwing on 409 —
|
|
105
|
+
* `winner: false` means another agent beat you to it.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* const claim = await tasks.claim({ workspaceSlug, actorSessionToken, taskId });
|
|
110
|
+
* if (!claim.winner) {
|
|
111
|
+
* console.log("Lost race:", claim.conflict?.message);
|
|
112
|
+
* return;
|
|
113
|
+
* }
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
claim(input: ClaimInput): Promise<ClaimResult>;
|
|
117
|
+
/**
|
|
118
|
+
* Governor-only: arbitrate between two agents racing for the same task.
|
|
119
|
+
* Returns the server's decision without throwing.
|
|
120
|
+
*/
|
|
121
|
+
raceClaim(input: RaceClaimInput): Promise<RaceClaimResultEnvelope>;
|
|
122
|
+
/**
|
|
123
|
+
* Mark a claimed task complete, attaching the delivered artifact.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* await tasks.complete({
|
|
128
|
+
* workspaceSlug, actorSessionToken, taskId,
|
|
129
|
+
* artifact: { kind: "text", content: "All clear — no alerts triaged." }
|
|
130
|
+
* });
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
complete(input: CompleteInput): Promise<TaskChargeEnvelope>;
|
|
134
|
+
/**
|
|
135
|
+
* Watch a task for state changes. Routes through a {@link StreamClient}
|
|
136
|
+
* so consumers don't need to manage their own SSE connection.
|
|
137
|
+
*
|
|
138
|
+
* @returns An unsubscribe function that detaches the handler.
|
|
139
|
+
*/
|
|
140
|
+
watch(stream: StreamClient, taskId: string, handler: (event: {
|
|
141
|
+
type: string;
|
|
142
|
+
payload: unknown;
|
|
143
|
+
}) => void): Unsubscribe;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=tasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/modules/tasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-level task lifecycle helpers.
|
|
3
|
+
*
|
|
4
|
+
* Wraps `/v1/workspaces/:slug/objectives` and `/v1/workspaces/:slug/tasks/*`
|
|
5
|
+
* with typed inputs, idempotency key generation, and conflict-tolerant claim
|
|
6
|
+
* semantics so agents can work without writing bespoke JSON by hand.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import { ConflictError } from "../errors.js";
|
|
11
|
+
import { idempotencyKey } from "../retry.js";
|
|
12
|
+
function idemHeader(key) {
|
|
13
|
+
return { "idempotency-key": key };
|
|
14
|
+
}
|
|
15
|
+
/** Workspace-scoped task client. */
|
|
16
|
+
export class TasksClient {
|
|
17
|
+
http;
|
|
18
|
+
constructor(http) {
|
|
19
|
+
this.http = http;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Create an objective. Governor role required.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* const { objective } = await tasks.createObjective({
|
|
27
|
+
* workspaceSlug: "ws_1",
|
|
28
|
+
* actorSessionToken,
|
|
29
|
+
* title: "Triage overnight alerts"
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
async createObjective(input) {
|
|
34
|
+
const key = input.idempotencyKey ?? idempotencyKey(`objective:${input.workspaceSlug}`);
|
|
35
|
+
return this.http.request({
|
|
36
|
+
path: `/v1/workspaces/${encodeURIComponent(input.workspaceSlug)}/objectives`,
|
|
37
|
+
method: "POST",
|
|
38
|
+
operation: "objective-create",
|
|
39
|
+
headers: this.http.bearerHeaders(input.actorSessionToken, idemHeader(key)),
|
|
40
|
+
body: {
|
|
41
|
+
title: input.title,
|
|
42
|
+
...(input.spec ? { spec: input.spec } : {})
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Create a standalone task under an existing objective.
|
|
48
|
+
*
|
|
49
|
+
* Agents can create tasks for themselves — the control-plane enforces
|
|
50
|
+
* lease charging for agent-authored tasks automatically.
|
|
51
|
+
*/
|
|
52
|
+
async createTask(input) {
|
|
53
|
+
const key = input.idempotencyKey ?? idempotencyKey(`task:${input.objectiveId}`);
|
|
54
|
+
return this.http.request({
|
|
55
|
+
path: `/v1/workspaces/${encodeURIComponent(input.workspaceSlug)}/tasks`,
|
|
56
|
+
method: "POST",
|
|
57
|
+
operation: "task-create",
|
|
58
|
+
headers: this.http.bearerHeaders(input.actorSessionToken, idemHeader(key)),
|
|
59
|
+
body: {
|
|
60
|
+
objectiveId: input.objectiveId,
|
|
61
|
+
...(input.priority !== undefined ? { priority: input.priority } : {}),
|
|
62
|
+
...(input.spec ? { spec: input.spec } : {})
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Claim a task. Returns a {@link ClaimResult} instead of throwing on 409 —
|
|
68
|
+
* `winner: false` means another agent beat you to it.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* const claim = await tasks.claim({ workspaceSlug, actorSessionToken, taskId });
|
|
73
|
+
* if (!claim.winner) {
|
|
74
|
+
* console.log("Lost race:", claim.conflict?.message);
|
|
75
|
+
* return;
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
async claim(input) {
|
|
80
|
+
const key = input.idempotencyKey ?? idempotencyKey(`claim:${input.taskId}`);
|
|
81
|
+
try {
|
|
82
|
+
const payload = await this.http.request({
|
|
83
|
+
path: `/v1/workspaces/${encodeURIComponent(input.workspaceSlug)}/tasks/${encodeURIComponent(input.taskId)}/claim`,
|
|
84
|
+
method: "POST",
|
|
85
|
+
operation: "task-claim",
|
|
86
|
+
headers: this.http.bearerHeaders(input.actorSessionToken, idemHeader(key)),
|
|
87
|
+
body: {}
|
|
88
|
+
});
|
|
89
|
+
return {
|
|
90
|
+
winner: true,
|
|
91
|
+
task: payload.task,
|
|
92
|
+
...(payload.chargeUnits !== undefined ? { chargeUnits: payload.chargeUnits } : {}),
|
|
93
|
+
...(payload.remainingSpendUnits !== undefined
|
|
94
|
+
? { remainingSpendUnits: payload.remainingSpendUnits }
|
|
95
|
+
: {}),
|
|
96
|
+
...(payload.pricingVersion !== undefined ? { pricingVersion: payload.pricingVersion } : {})
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (error instanceof ConflictError) {
|
|
101
|
+
return { winner: false, conflict: error };
|
|
102
|
+
}
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Governor-only: arbitrate between two agents racing for the same task.
|
|
108
|
+
* Returns the server's decision without throwing.
|
|
109
|
+
*/
|
|
110
|
+
async raceClaim(input) {
|
|
111
|
+
const key = input.idempotencyKey ?? idempotencyKey(`race-claim:${input.taskId}`);
|
|
112
|
+
return this.http.request({
|
|
113
|
+
path: `/v1/workspaces/${encodeURIComponent(input.workspaceSlug)}/tasks/${encodeURIComponent(input.taskId)}/race-claim`,
|
|
114
|
+
method: "POST",
|
|
115
|
+
operation: "task-race-claim",
|
|
116
|
+
headers: this.http.bearerHeaders(input.actorSessionToken, idemHeader(key)),
|
|
117
|
+
body: {
|
|
118
|
+
agentAIdentity: input.agentAIdentity,
|
|
119
|
+
agentBIdentity: input.agentBIdentity
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Mark a claimed task complete, attaching the delivered artifact.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* await tasks.complete({
|
|
129
|
+
* workspaceSlug, actorSessionToken, taskId,
|
|
130
|
+
* artifact: { kind: "text", content: "All clear — no alerts triaged." }
|
|
131
|
+
* });
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
async complete(input) {
|
|
135
|
+
const key = input.idempotencyKey ?? idempotencyKey(`complete:${input.taskId}`);
|
|
136
|
+
return this.http.request({
|
|
137
|
+
path: `/v1/workspaces/${encodeURIComponent(input.workspaceSlug)}/tasks/${encodeURIComponent(input.taskId)}/complete`,
|
|
138
|
+
method: "POST",
|
|
139
|
+
operation: "task-complete",
|
|
140
|
+
headers: this.http.bearerHeaders(input.actorSessionToken, idemHeader(key)),
|
|
141
|
+
body: {
|
|
142
|
+
artifact: {
|
|
143
|
+
kind: input.artifact.kind,
|
|
144
|
+
content: input.artifact.content
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Watch a task for state changes. Routes through a {@link StreamClient}
|
|
151
|
+
* so consumers don't need to manage their own SSE connection.
|
|
152
|
+
*
|
|
153
|
+
* @returns An unsubscribe function that detaches the handler.
|
|
154
|
+
*/
|
|
155
|
+
watch(stream, taskId, handler) {
|
|
156
|
+
const unsubscribe = stream.onAny((event) => {
|
|
157
|
+
const payload = event.payload;
|
|
158
|
+
if (payload && (payload.taskId === taskId || payload.id === taskId)) {
|
|
159
|
+
handler({ type: event.type, payload: event.payload });
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
return unsubscribe;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/modules/tasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured telemetry.
|
|
3
|
+
*
|
|
4
|
+
* Every SDK operation can emit a {@link TelemetryEvent} describing what
|
|
5
|
+
* happened, how long it took, and whether it succeeded. The default sink
|
|
6
|
+
* prints JSON lines to stdout; callers can swap in an OpenTelemetry
|
|
7
|
+
* bridge, Datadog forwarder, or any custom function.
|
|
8
|
+
*
|
|
9
|
+
* Telemetry is **opt-in**. Pass `telemetry: { sink }` to
|
|
10
|
+
* {@link AgentSdkClient} (or any module that accepts it) to enable.
|
|
11
|
+
*
|
|
12
|
+
* Invariants:
|
|
13
|
+
* - A failing sink never crashes the caller — exceptions are swallowed.
|
|
14
|
+
* - Event emission is synchronous from the caller's perspective (no await).
|
|
15
|
+
* - Event shape is stable — future fields are additive.
|
|
16
|
+
*
|
|
17
|
+
* @packageDocumentation
|
|
18
|
+
*/
|
|
19
|
+
/** Outcome of a telemetry span. */
|
|
20
|
+
export type TelemetryOutcome = "success" | "error" | "cancelled";
|
|
21
|
+
/** Structured event shape emitted for every instrumented operation. */
|
|
22
|
+
export interface TelemetryEvent {
|
|
23
|
+
/** Epoch-ms when the event was emitted. */
|
|
24
|
+
timestamp: number;
|
|
25
|
+
/** Stable operation key — usually the SDK method or HTTP path family. */
|
|
26
|
+
operation: string;
|
|
27
|
+
/** Wall-clock duration of the operation in milliseconds. */
|
|
28
|
+
duration_ms: number;
|
|
29
|
+
/** Outcome classification. */
|
|
30
|
+
outcome: TelemetryOutcome;
|
|
31
|
+
/** True when `outcome === "success"`. Retained for ergonomics. */
|
|
32
|
+
success: boolean;
|
|
33
|
+
/** `ShardLinkError.code` when outcome is error. */
|
|
34
|
+
error_code?: string;
|
|
35
|
+
/** HTTP status (0 when not HTTP-originated or unknown). */
|
|
36
|
+
http_status?: number;
|
|
37
|
+
/** Whether this error would trigger SDK auto-retry. */
|
|
38
|
+
retryable?: boolean;
|
|
39
|
+
/** Correlation id when the server returned one. */
|
|
40
|
+
correlation_id?: string;
|
|
41
|
+
/** Workspace slug (set for workspace-scoped ops). */
|
|
42
|
+
workspace?: string;
|
|
43
|
+
/** Task id (set for task lifecycle ops). */
|
|
44
|
+
task_id?: string;
|
|
45
|
+
/** Estimated/actual cost in USD cents (set by billing-related ops). */
|
|
46
|
+
cost_cents?: number;
|
|
47
|
+
/** Tracing span id for correlation across systems. */
|
|
48
|
+
span_id?: string;
|
|
49
|
+
/** Parent span id when this span nests inside another. */
|
|
50
|
+
parent_span_id?: string;
|
|
51
|
+
/** Free-form attributes. Flat — no nested objects. Values must be primitives. */
|
|
52
|
+
attrs?: Record<string, string | number | boolean>;
|
|
53
|
+
}
|
|
54
|
+
/** Sink signature — accepts an event, returns nothing (or a promise we don't await). */
|
|
55
|
+
export type TelemetrySink = (event: TelemetryEvent) => void;
|
|
56
|
+
/** Options accepted by the telemetry client. */
|
|
57
|
+
export interface TelemetryClientOptions {
|
|
58
|
+
/** Destination — defaults to stdout JSON lines. Set `enabled: false` for a no-op. */
|
|
59
|
+
sink?: TelemetrySink;
|
|
60
|
+
/** Hard kill switch (honored even when a sink is provided). */
|
|
61
|
+
enabled?: boolean;
|
|
62
|
+
/** Static attributes merged into every event. */
|
|
63
|
+
baseAttrs?: Record<string, string | number | boolean>;
|
|
64
|
+
}
|
|
65
|
+
/** Sink that forwards events to an OpenTelemetry tracer. */
|
|
66
|
+
export interface OpenTelemetryBridge {
|
|
67
|
+
/** Given an event, emit it as a span through the tracer. */
|
|
68
|
+
emit(event: TelemetryEvent): void;
|
|
69
|
+
}
|
|
70
|
+
/** Span handle returned by {@link TelemetryClient.start}. */
|
|
71
|
+
export interface TelemetrySpan {
|
|
72
|
+
readonly operation: string;
|
|
73
|
+
readonly spanId: string;
|
|
74
|
+
/** Attach ad-hoc attributes before finishing. */
|
|
75
|
+
set(attrs: Partial<Omit<TelemetryEvent, "timestamp" | "duration_ms" | "operation">>): void;
|
|
76
|
+
/** Mark the span successful and emit. */
|
|
77
|
+
end(outcomeAttrs?: Partial<TelemetryEvent>): void;
|
|
78
|
+
/** Mark the span errored with the given error and emit. */
|
|
79
|
+
fail(error: unknown, outcomeAttrs?: Partial<TelemetryEvent>): void;
|
|
80
|
+
/** Mark the span cancelled (e.g. abort). */
|
|
81
|
+
cancel(outcomeAttrs?: Partial<TelemetryEvent>): void;
|
|
82
|
+
}
|
|
83
|
+
/** JSON-line stdout sink — safe default. */
|
|
84
|
+
export declare const defaultSink: TelemetrySink;
|
|
85
|
+
/** A sink that drops every event — used when telemetry is disabled. */
|
|
86
|
+
export declare const noopSink: TelemetrySink;
|
|
87
|
+
/**
|
|
88
|
+
* Lightweight telemetry emitter. Instances are safe to share across the SDK.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* const telemetry = new TelemetryClient({ sink: defaultSink });
|
|
93
|
+
* const span = telemetry.start("task-claim", { workspace: "ws_1" });
|
|
94
|
+
* try {
|
|
95
|
+
* const result = await tasks.claim({ ... });
|
|
96
|
+
* span.end({ task_id: result.task?.id });
|
|
97
|
+
* } catch (err) {
|
|
98
|
+
* span.fail(err);
|
|
99
|
+
* throw err;
|
|
100
|
+
* }
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export declare class TelemetryClient {
|
|
104
|
+
private readonly sink;
|
|
105
|
+
private readonly baseAttrs;
|
|
106
|
+
private readonly enabled;
|
|
107
|
+
constructor(options?: TelemetryClientOptions);
|
|
108
|
+
/** Emit a pre-built event. Use {@link start} when you need duration tracking. */
|
|
109
|
+
emit(event: TelemetryEvent): void;
|
|
110
|
+
/** Begin a span; call `.end()`, `.fail()`, or `.cancel()` when the operation finishes. */
|
|
111
|
+
start(operation: string, seed?: Partial<Omit<TelemetryEvent, "timestamp" | "duration_ms" | "operation">>): TelemetrySpan;
|
|
112
|
+
/** Wrap an async operation with a telemetry span. */
|
|
113
|
+
instrument<T>(operation: string, fn: (span: TelemetrySpan) => Promise<T>, seed?: Partial<Omit<TelemetryEvent, "timestamp" | "duration_ms" | "operation">>): Promise<T>;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Build a sink that forwards every event to an OpenTelemetry-compatible
|
|
117
|
+
* tracer (or any object with an `emit(event)` method). Use this to hook
|
|
118
|
+
* the SDK into your existing observability stack without building custom
|
|
119
|
+
* plumbing.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* const bridge = {
|
|
124
|
+
* emit(event) {
|
|
125
|
+
* tracer.startSpan(event.operation, { attributes: { ...event.attrs, duration_ms: event.duration_ms } }).end();
|
|
126
|
+
* }
|
|
127
|
+
* };
|
|
128
|
+
* const telemetry = new TelemetryClient({ sink: openTelemetrySink(bridge) });
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
export declare function openTelemetrySink(bridge: OpenTelemetryBridge): TelemetrySink;
|
|
132
|
+
/**
|
|
133
|
+
* Compose multiple sinks into one (fan-out). Every sink receives every
|
|
134
|
+
* event; failures in one don't block the others.
|
|
135
|
+
*/
|
|
136
|
+
export declare function multiSink(...sinks: TelemetrySink[]): TelemetrySink;
|
|
137
|
+
//# sourceMappingURL=telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/modules/telemetry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured telemetry.
|
|
3
|
+
*
|
|
4
|
+
* Every SDK operation can emit a {@link TelemetryEvent} describing what
|
|
5
|
+
* happened, how long it took, and whether it succeeded. The default sink
|
|
6
|
+
* prints JSON lines to stdout; callers can swap in an OpenTelemetry
|
|
7
|
+
* bridge, Datadog forwarder, or any custom function.
|
|
8
|
+
*
|
|
9
|
+
* Telemetry is **opt-in**. Pass `telemetry: { sink }` to
|
|
10
|
+
* {@link AgentSdkClient} (or any module that accepts it) to enable.
|
|
11
|
+
*
|
|
12
|
+
* Invariants:
|
|
13
|
+
* - A failing sink never crashes the caller — exceptions are swallowed.
|
|
14
|
+
* - Event emission is synchronous from the caller's perspective (no await).
|
|
15
|
+
* - Event shape is stable — future fields are additive.
|
|
16
|
+
*
|
|
17
|
+
* @packageDocumentation
|
|
18
|
+
*/
|
|
19
|
+
/** JSON-line stdout sink — safe default. */
|
|
20
|
+
export const defaultSink = (event) => {
|
|
21
|
+
try {
|
|
22
|
+
console.log(JSON.stringify(event));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// never let logging break the caller
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
/** A sink that drops every event — used when telemetry is disabled. */
|
|
29
|
+
export const noopSink = () => {
|
|
30
|
+
// deliberate no-op
|
|
31
|
+
};
|
|
32
|
+
function generateSpanId() {
|
|
33
|
+
const rand = typeof globalThis.crypto?.randomUUID === "function"
|
|
34
|
+
? globalThis.crypto.randomUUID()
|
|
35
|
+
: Math.random().toString(16).slice(2);
|
|
36
|
+
return rand.replace(/-/g, "").slice(0, 16);
|
|
37
|
+
}
|
|
38
|
+
function isShardLinkError(value) {
|
|
39
|
+
return (typeof value === "object" &&
|
|
40
|
+
value !== null &&
|
|
41
|
+
"code" in value &&
|
|
42
|
+
"status" in value &&
|
|
43
|
+
"retryable" in value);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Lightweight telemetry emitter. Instances are safe to share across the SDK.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const telemetry = new TelemetryClient({ sink: defaultSink });
|
|
51
|
+
* const span = telemetry.start("task-claim", { workspace: "ws_1" });
|
|
52
|
+
* try {
|
|
53
|
+
* const result = await tasks.claim({ ... });
|
|
54
|
+
* span.end({ task_id: result.task?.id });
|
|
55
|
+
* } catch (err) {
|
|
56
|
+
* span.fail(err);
|
|
57
|
+
* throw err;
|
|
58
|
+
* }
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export class TelemetryClient {
|
|
62
|
+
sink;
|
|
63
|
+
baseAttrs;
|
|
64
|
+
enabled;
|
|
65
|
+
constructor(options = {}) {
|
|
66
|
+
this.enabled = options.enabled !== false;
|
|
67
|
+
this.sink = this.enabled ? (options.sink ?? defaultSink) : noopSink;
|
|
68
|
+
this.baseAttrs = options.baseAttrs ?? {};
|
|
69
|
+
}
|
|
70
|
+
/** Emit a pre-built event. Use {@link start} when you need duration tracking. */
|
|
71
|
+
emit(event) {
|
|
72
|
+
if (!this.enabled)
|
|
73
|
+
return;
|
|
74
|
+
const merged = {
|
|
75
|
+
...event,
|
|
76
|
+
attrs: { ...this.baseAttrs, ...(event.attrs ?? {}) }
|
|
77
|
+
};
|
|
78
|
+
try {
|
|
79
|
+
this.sink(merged);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// swallow sink failures
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** Begin a span; call `.end()`, `.fail()`, or `.cancel()` when the operation finishes. */
|
|
86
|
+
start(operation, seed = {}) {
|
|
87
|
+
const startedAt = Date.now();
|
|
88
|
+
const spanId = seed.span_id ?? generateSpanId();
|
|
89
|
+
let additions = { ...seed, span_id: spanId };
|
|
90
|
+
let finished = false;
|
|
91
|
+
const finalize = (outcome, extra = {}) => {
|
|
92
|
+
if (finished)
|
|
93
|
+
return;
|
|
94
|
+
finished = true;
|
|
95
|
+
const merged = {
|
|
96
|
+
timestamp: Date.now(),
|
|
97
|
+
operation,
|
|
98
|
+
duration_ms: Date.now() - startedAt,
|
|
99
|
+
outcome,
|
|
100
|
+
success: outcome === "success",
|
|
101
|
+
...additions,
|
|
102
|
+
...extra,
|
|
103
|
+
attrs: {
|
|
104
|
+
...this.baseAttrs,
|
|
105
|
+
...(additions.attrs ?? {}),
|
|
106
|
+
...(extra.attrs ?? {})
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
this.emit(merged);
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
operation,
|
|
113
|
+
spanId,
|
|
114
|
+
set(attrs) {
|
|
115
|
+
additions = {
|
|
116
|
+
...additions,
|
|
117
|
+
...attrs,
|
|
118
|
+
attrs: { ...(additions.attrs ?? {}), ...(attrs.attrs ?? {}) }
|
|
119
|
+
};
|
|
120
|
+
},
|
|
121
|
+
end(outcomeAttrs) {
|
|
122
|
+
finalize("success", outcomeAttrs ?? {});
|
|
123
|
+
},
|
|
124
|
+
fail(error, outcomeAttrs) {
|
|
125
|
+
const errAttrs = {};
|
|
126
|
+
if (isShardLinkError(error)) {
|
|
127
|
+
errAttrs.error_code = error.code;
|
|
128
|
+
errAttrs.http_status = error.status;
|
|
129
|
+
errAttrs.retryable = error.retryable;
|
|
130
|
+
if (error.correlationId)
|
|
131
|
+
errAttrs.correlation_id = error.correlationId;
|
|
132
|
+
}
|
|
133
|
+
else if (error instanceof Error) {
|
|
134
|
+
errAttrs.error_code = "unknown_error";
|
|
135
|
+
errAttrs.attrs = { error_message: error.message };
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
errAttrs.error_code = "unknown_error";
|
|
139
|
+
}
|
|
140
|
+
finalize("error", { ...errAttrs, ...(outcomeAttrs ?? {}) });
|
|
141
|
+
},
|
|
142
|
+
cancel(outcomeAttrs) {
|
|
143
|
+
finalize("cancelled", outcomeAttrs ?? {});
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/** Wrap an async operation with a telemetry span. */
|
|
148
|
+
async instrument(operation, fn, seed = {}) {
|
|
149
|
+
const span = this.start(operation, seed);
|
|
150
|
+
try {
|
|
151
|
+
const result = await fn(span);
|
|
152
|
+
span.end();
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
span.fail(err);
|
|
157
|
+
throw err;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Build a sink that forwards every event to an OpenTelemetry-compatible
|
|
163
|
+
* tracer (or any object with an `emit(event)` method). Use this to hook
|
|
164
|
+
* the SDK into your existing observability stack without building custom
|
|
165
|
+
* plumbing.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```ts
|
|
169
|
+
* const bridge = {
|
|
170
|
+
* emit(event) {
|
|
171
|
+
* tracer.startSpan(event.operation, { attributes: { ...event.attrs, duration_ms: event.duration_ms } }).end();
|
|
172
|
+
* }
|
|
173
|
+
* };
|
|
174
|
+
* const telemetry = new TelemetryClient({ sink: openTelemetrySink(bridge) });
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
export function openTelemetrySink(bridge) {
|
|
178
|
+
return (event) => {
|
|
179
|
+
try {
|
|
180
|
+
bridge.emit(event);
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// swallow — telemetry must not break callers
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Compose multiple sinks into one (fan-out). Every sink receives every
|
|
189
|
+
* event; failures in one don't block the others.
|
|
190
|
+
*/
|
|
191
|
+
export function multiSink(...sinks) {
|
|
192
|
+
return (event) => {
|
|
193
|
+
for (const sink of sinks) {
|
|
194
|
+
try {
|
|
195
|
+
sink(event);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// ignore per-sink failure
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/modules/telemetry.ts"],"names":[],"mappings":"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"}
|