@tier0/sdk-v2 0.6.3 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -9
- package/dist/cjs/capabilities.d.ts +20 -4
- package/dist/cjs/capabilities.js +66 -6
- package/dist/cjs/capabilities.js.map +1 -1
- package/dist/cjs/client.d.ts +9 -7
- package/dist/cjs/client.js +0 -2
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/cloud-transport.d.ts +3 -2
- package/dist/cjs/cloud-transport.js +8 -7
- package/dist/cjs/cloud-transport.js.map +1 -1
- package/dist/cjs/index.d.ts +0 -1
- package/dist/cjs/index.js +0 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/openapi/api.generated.d.ts +9 -5
- package/dist/cjs/openapi/codecs.generated.d.ts +943 -684
- package/dist/cjs/openapi/codecs.generated.js +1 -1
- package/dist/cjs/openapi/codecs.generated.js.map +1 -1
- package/dist/cjs/openapi/types.generated.d.ts +638 -508
- package/dist/cjs/openapi/types.generated.js.map +1 -1
- package/dist/cjs/uns-v2/client.js +2 -2
- package/dist/cjs/uns-v2/client.js.map +1 -1
- package/dist/cjs/uns-v2/generated.d.ts +182 -253
- package/dist/cjs/uns-v2/generated.js +16 -19
- package/dist/cjs/uns-v2/generated.js.map +1 -1
- package/dist/esm/capabilities.d.ts +20 -4
- package/dist/esm/capabilities.js +66 -6
- package/dist/esm/capabilities.js.map +1 -1
- package/dist/esm/client.d.ts +9 -7
- package/dist/esm/client.js +0 -2
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/cloud-transport.d.ts +3 -2
- package/dist/esm/cloud-transport.js +8 -7
- package/dist/esm/cloud-transport.js.map +1 -1
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/openapi/api.generated.d.ts +9 -5
- package/dist/esm/openapi/codecs.generated.d.ts +943 -684
- package/dist/esm/openapi/codecs.generated.js +1 -1
- package/dist/esm/openapi/codecs.generated.js.map +1 -1
- package/dist/esm/openapi/types.generated.d.ts +638 -508
- package/dist/esm/openapi/types.generated.js.map +1 -1
- package/dist/esm/uns-v2/client.js +2 -2
- package/dist/esm/uns-v2/client.js.map +1 -1
- package/dist/esm/uns-v2/generated.d.ts +182 -253
- package/dist/esm/uns-v2/generated.js +16 -19
- package/dist/esm/uns-v2/generated.js.map +1 -1
- package/package.json +5 -7
- package/skills/tier0-sdk-v2/SKILL.md +14 -4
- package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/SKILL.md +1 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/references/quickstart.md +1 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/SKILL.md +2 -2
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/create.md +10 -6
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/protocols.md +1 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/SKILL.md +1 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/create.md +6 -2
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/http-server.md +1 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/lifecycle.md +2 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/read.md +4 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-system/SKILL.md +7 -2
- package/dist/cjs/controls.d.ts +0 -105
- package/dist/cjs/controls.js +0 -172
- package/dist/cjs/controls.js.map +0 -1
- package/dist/esm/controls.d.ts +0 -105
- package/dist/esm/controls.js +0 -166
- package/dist/esm/controls.js.map +0 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-controls/SKILL.md +0 -65
package/dist/esm/controls.d.ts
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { type HttpClient, type ClientConfig } from './openapi/client.js';
|
|
2
|
-
import { type CloudTransportConfig } from './cloud-transport.js';
|
|
3
|
-
import { type UnsV2Execution, type UnsV2Retry } from './uns-v2/client.js';
|
|
4
|
-
import type { UnsV2JSONValue } from './uns-v2/generated.js';
|
|
5
|
-
/** Control convenience API over the canonical UNS v2 routes. Exact numbers are preserved. */
|
|
6
|
-
export type ControlJSON = UnsV2JSONValue;
|
|
7
|
-
export interface PublicControl {
|
|
8
|
-
code: string;
|
|
9
|
-
name: string;
|
|
10
|
-
description: string;
|
|
11
|
-
contractVersion: string;
|
|
12
|
-
inputSchema: Record<string, ControlJSON>;
|
|
13
|
-
outputSchema: Record<string, ControlJSON>;
|
|
14
|
-
sideEffect: 'read' | 'write';
|
|
15
|
-
idempotency: 'none' | 'optional' | 'required';
|
|
16
|
-
timeoutMs: number;
|
|
17
|
-
status: string;
|
|
18
|
-
}
|
|
19
|
-
export interface ControlDiscoverOptions {
|
|
20
|
-
page?: number;
|
|
21
|
-
size?: number;
|
|
22
|
-
search?: string;
|
|
23
|
-
}
|
|
24
|
-
export interface ControlDiscoverResponse {
|
|
25
|
-
total: number;
|
|
26
|
-
list: PublicControl[];
|
|
27
|
-
}
|
|
28
|
-
/** Shared HTTP settings. The server still resolves the Control binding and authorization. */
|
|
29
|
-
export interface ControlTransportConfig extends CloudTransportConfig {
|
|
30
|
-
}
|
|
31
|
-
export interface CloudClientConfig extends ClientConfig, ControlTransportConfig {
|
|
32
|
-
}
|
|
33
|
-
export declare const DEFAULT_CONTROL_TRANSPORT_TIMEOUT_MS = 60000;
|
|
34
|
-
export interface ControlInvokeOptions {
|
|
35
|
-
/** Stable caller-owned key for one business intent, at most 128 UTF-8 bytes. Never generated or retried by the SDK. */
|
|
36
|
-
idempotencyKey?: string;
|
|
37
|
-
}
|
|
38
|
-
export interface ControlInvokeResponse<Result = ControlJSON> {
|
|
39
|
-
code: string;
|
|
40
|
-
contractVersion: string;
|
|
41
|
-
result: Result;
|
|
42
|
-
runID: string;
|
|
43
|
-
status: string;
|
|
44
|
-
/** True only when the server explicitly reports an idempotent replay. */
|
|
45
|
-
replayed: boolean;
|
|
46
|
-
}
|
|
47
|
-
export interface ControlErrorInfo {
|
|
48
|
-
/** HTTP status, absent when no HTTP response was received. */
|
|
49
|
-
status?: number;
|
|
50
|
-
/** Canonical UNS error.code, or an SDK-local CONTROL_* transport/protocol code. */
|
|
51
|
-
errorCode: string;
|
|
52
|
-
runID?: string;
|
|
53
|
-
contractVersion?: string;
|
|
54
|
-
runStatus?: string;
|
|
55
|
-
replayed?: boolean;
|
|
56
|
-
requestId?: string;
|
|
57
|
-
execution?: UnsV2Execution;
|
|
58
|
-
retry?: UnsV2Retry;
|
|
59
|
-
reason?: string;
|
|
60
|
-
details?: Record<string, unknown>[];
|
|
61
|
-
data?: unknown;
|
|
62
|
-
}
|
|
63
|
-
/** No Control error is automatically retried, including authentication failures. */
|
|
64
|
-
export declare class ControlError extends Error {
|
|
65
|
-
readonly status?: number;
|
|
66
|
-
readonly errorCode: string;
|
|
67
|
-
readonly runID?: string;
|
|
68
|
-
readonly contractVersion?: string;
|
|
69
|
-
readonly runStatus?: string;
|
|
70
|
-
readonly replayed?: boolean;
|
|
71
|
-
readonly requestId?: string;
|
|
72
|
-
readonly execution?: UnsV2Execution;
|
|
73
|
-
readonly retry?: UnsV2Retry;
|
|
74
|
-
readonly reason?: string;
|
|
75
|
-
readonly details?: Record<string, unknown>[];
|
|
76
|
-
readonly data?: unknown;
|
|
77
|
-
readonly retryable = false;
|
|
78
|
-
constructor(message: string, info: ControlErrorInfo);
|
|
79
|
-
}
|
|
80
|
-
/** Execution may have happened. Reconcile run information; any deliberate replay must reuse the same key. */
|
|
81
|
-
export declare class ControlResultUnknownError extends ControlError {
|
|
82
|
-
readonly outcomeUnknown = true;
|
|
83
|
-
constructor(info: ControlErrorInfo);
|
|
84
|
-
}
|
|
85
|
-
export interface ControlHandle<Input = ControlJSON, Result = ControlJSON> {
|
|
86
|
-
describe(): Promise<PublicControl>;
|
|
87
|
-
/**
|
|
88
|
-
* One POST only. Input is opaque business JSON, including fields named streamId,
|
|
89
|
-
* entryId, deploymentVersion or timeoutMs. Only the server chooses binding/version/timeout.
|
|
90
|
-
* Generic types are caller assertions; the server validates the contract schemas.
|
|
91
|
-
*/
|
|
92
|
-
invoke(input: Input, options?: ControlInvokeOptions): Promise<ControlInvokeResponse<Result>>;
|
|
93
|
-
}
|
|
94
|
-
export declare class ControlsClient {
|
|
95
|
-
private readonly uns;
|
|
96
|
-
constructor(resolveClient?: () => HttpClient, config?: ControlTransportConfig);
|
|
97
|
-
private post;
|
|
98
|
-
/** Discover visible contracts; defaults and authorization are resolved by the server. */
|
|
99
|
-
discover(options?: ControlDiscoverOptions): Promise<ControlDiscoverResponse>;
|
|
100
|
-
use<Input = ControlJSON, Result = ControlJSON>(selector: {
|
|
101
|
-
code: string;
|
|
102
|
-
}): ControlHandle<Input, Result>;
|
|
103
|
-
}
|
|
104
|
-
/** Uses configureClient()/TIER0_API_HOST/TIER0_API_KEY, resolved for every call. */
|
|
105
|
-
export declare const controls: ControlsClient;
|
package/dist/esm/controls.js
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { getClient } from './openapi/client.js';
|
|
2
|
-
import { DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS } from './cloud-transport.js';
|
|
3
|
-
import { UnsV2ClientCore, UnsV2Error } from './uns-v2/client.js';
|
|
4
|
-
import { UnsV2RawNumber } from './uns-v2/codec.js';
|
|
5
|
-
export const DEFAULT_CONTROL_TRANSPORT_TIMEOUT_MS = DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS;
|
|
6
|
-
/** No Control error is automatically retried, including authentication failures. */
|
|
7
|
-
export class ControlError extends Error {
|
|
8
|
-
status;
|
|
9
|
-
errorCode;
|
|
10
|
-
runID;
|
|
11
|
-
contractVersion;
|
|
12
|
-
runStatus;
|
|
13
|
-
replayed;
|
|
14
|
-
requestId;
|
|
15
|
-
execution;
|
|
16
|
-
retry;
|
|
17
|
-
reason;
|
|
18
|
-
details;
|
|
19
|
-
data;
|
|
20
|
-
retryable = false;
|
|
21
|
-
constructor(message, info) {
|
|
22
|
-
super(message);
|
|
23
|
-
this.name = 'ControlError';
|
|
24
|
-
this.status = info.status;
|
|
25
|
-
this.errorCode = info.errorCode;
|
|
26
|
-
this.runID = info.runID;
|
|
27
|
-
this.contractVersion = info.contractVersion;
|
|
28
|
-
this.runStatus = info.runStatus;
|
|
29
|
-
this.replayed = info.replayed;
|
|
30
|
-
this.requestId = info.requestId;
|
|
31
|
-
this.execution = info.execution;
|
|
32
|
-
this.retry = info.retry;
|
|
33
|
-
this.reason = info.reason;
|
|
34
|
-
this.details = info.details;
|
|
35
|
-
this.data = info.data;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
/** Execution may have happened. Reconcile run information; any deliberate replay must reuse the same key. */
|
|
39
|
-
export class ControlResultUnknownError extends ControlError {
|
|
40
|
-
outcomeUnknown = true;
|
|
41
|
-
constructor(info) {
|
|
42
|
-
super('Control result is unknown; execution may have occurred. Do not automatically retry.', info);
|
|
43
|
-
this.name = 'ControlResultUnknownError';
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
function record(value) {
|
|
47
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
48
|
-
}
|
|
49
|
-
function keys(value, allowed) {
|
|
50
|
-
if (!record(value) || Reflect.ownKeys(value).some(key => typeof key !== 'string' || !allowed.includes(key))) {
|
|
51
|
-
throw new TypeError('Tier0 SDK: unsupported Control option.');
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
function json(value, seen = new Set()) {
|
|
55
|
-
if (value === null || typeof value === 'string' || typeof value === 'boolean' || value instanceof UnsV2RawNumber)
|
|
56
|
-
return true;
|
|
57
|
-
if (typeof value === 'number')
|
|
58
|
-
return Number.isFinite(value);
|
|
59
|
-
if (typeof value !== 'object' || seen.has(value))
|
|
60
|
-
return false;
|
|
61
|
-
if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
seen.add(value);
|
|
65
|
-
const valid = (Array.isArray(value) ? Array.from(value) : Object.values(value)).every(item => json(item, seen));
|
|
66
|
-
seen.delete(value);
|
|
67
|
-
return valid;
|
|
68
|
-
}
|
|
69
|
-
function definition(value) {
|
|
70
|
-
if (!record(value))
|
|
71
|
-
return false;
|
|
72
|
-
return ['code', 'name', 'description', 'contractVersion', 'status'].every(key => typeof value[key] === 'string') &&
|
|
73
|
-
value.code !== '' && value.contractVersion !== '' && record(value.inputSchema) && record(value.outputSchema) &&
|
|
74
|
-
['read', 'write'].includes(value.sideEffect) &&
|
|
75
|
-
['none', 'optional', 'required'].includes(value.idempotency) &&
|
|
76
|
-
typeof value.timeoutMs === 'number' && Number.isSafeInteger(value.timeoutMs) && value.timeoutMs > 0;
|
|
77
|
-
}
|
|
78
|
-
function runInfo(value) {
|
|
79
|
-
if (!record(value))
|
|
80
|
-
return {};
|
|
81
|
-
return {
|
|
82
|
-
runID: typeof value.runId === 'string' ? value.runId : undefined,
|
|
83
|
-
contractVersion: typeof value.contractVersion === 'string' ? value.contractVersion : undefined,
|
|
84
|
-
runStatus: typeof value.status === 'string' ? value.status : undefined,
|
|
85
|
-
replayed: typeof value.replayed === 'boolean' ? value.replayed : undefined,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
export class ControlsClient {
|
|
89
|
-
uns;
|
|
90
|
-
constructor(resolveClient = getClient, config = {}) {
|
|
91
|
-
this.uns = new UnsV2ClientCore(resolveClient, config);
|
|
92
|
-
}
|
|
93
|
-
async post(operation, body) {
|
|
94
|
-
try {
|
|
95
|
-
const response = await this.uns.call(operation, body);
|
|
96
|
-
return { value: response.data, status: 200 };
|
|
97
|
-
}
|
|
98
|
-
catch (error) {
|
|
99
|
-
if (!(error instanceof UnsV2Error))
|
|
100
|
-
throw error;
|
|
101
|
-
const info = {
|
|
102
|
-
...runInfo(error.data), status: error.status,
|
|
103
|
-
errorCode: error.code.replace(/^UNS_V2_/, 'CONTROL_'),
|
|
104
|
-
requestId: error.requestId, execution: error.execution, retry: error.retry,
|
|
105
|
-
reason: error.reason, details: error.details, data: error.data,
|
|
106
|
-
};
|
|
107
|
-
if (error.outcomeUnknown)
|
|
108
|
-
throw new ControlResultUnknownError(info);
|
|
109
|
-
throw new ControlError(error.message, info);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
/** Discover visible contracts; defaults and authorization are resolved by the server. */
|
|
113
|
-
async discover(options = {}) {
|
|
114
|
-
keys(options, ['page', 'size', 'search']);
|
|
115
|
-
if ((options.page !== undefined && (!Number.isSafeInteger(options.page) || options.page < 1)) ||
|
|
116
|
-
(options.size !== undefined && (!Number.isSafeInteger(options.size) || options.size < 1 || options.size > 200)) ||
|
|
117
|
-
(options.search !== undefined && typeof options.search !== 'string')) {
|
|
118
|
-
throw new TypeError('Tier0 SDK: invalid Control discovery options.');
|
|
119
|
-
}
|
|
120
|
-
const { value, status } = await this.post('controlDiscover', options);
|
|
121
|
-
if (!record(value) || !Number.isSafeInteger(value.total) || value.total < 0 ||
|
|
122
|
-
!Array.isArray(value.list) || !value.list.every(definition)) {
|
|
123
|
-
throw new ControlError('Invalid Control discovery response.', { status, errorCode: 'CONTROL_PROTOCOL_ERROR' });
|
|
124
|
-
}
|
|
125
|
-
return { total: value.total, list: value.list };
|
|
126
|
-
}
|
|
127
|
-
use(selector) {
|
|
128
|
-
keys(selector, ['code']);
|
|
129
|
-
const code = selector.code;
|
|
130
|
-
if (typeof code !== 'string' || code.length > 128 || !/^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/.test(code)) {
|
|
131
|
-
throw new TypeError('Tier0 SDK: invalid Control code.');
|
|
132
|
-
}
|
|
133
|
-
return {
|
|
134
|
-
describe: async () => {
|
|
135
|
-
const { value, status } = await this.post('controlDescribe', { code });
|
|
136
|
-
if (!definition(value) || value.code !== code) {
|
|
137
|
-
throw new ControlError('Invalid Control description.', { status, errorCode: 'CONTROL_PROTOCOL_ERROR' });
|
|
138
|
-
}
|
|
139
|
-
return value;
|
|
140
|
-
},
|
|
141
|
-
invoke: async (input, options = {}) => {
|
|
142
|
-
keys(options, ['idempotencyKey']);
|
|
143
|
-
const key = options.idempotencyKey;
|
|
144
|
-
if (key !== undefined && (typeof key !== 'string' || !key || key.trim() !== key || new TextEncoder().encode(key).length > 128)) {
|
|
145
|
-
throw new TypeError('Tier0 SDK: invalid Control idempotency key.');
|
|
146
|
-
}
|
|
147
|
-
if (!json(input))
|
|
148
|
-
throw new TypeError('Tier0 SDK: Control input must be JSON.');
|
|
149
|
-
const { value, status } = await this.post('controlInvoke', {
|
|
150
|
-
code, input: input, ...(key === undefined ? {} : { idempotencyKey: key }),
|
|
151
|
-
});
|
|
152
|
-
if (!record(value) || value.code !== code || typeof value.contractVersion !== 'string' || !value.contractVersion ||
|
|
153
|
-
!Object.prototype.hasOwnProperty.call(value, 'result') || typeof value.runId !== 'string' || !value.runId ||
|
|
154
|
-
typeof value.status !== 'string' || !value.status || ['accepted', 'queued', 'pending', 'running'].includes(value.status) ||
|
|
155
|
-
typeof value.replayed !== 'boolean') {
|
|
156
|
-
throw new ControlResultUnknownError({ ...runInfo(value), status, errorCode: 'CONTROL_PROTOCOL_ERROR' });
|
|
157
|
-
}
|
|
158
|
-
return { code: value.code, contractVersion: value.contractVersion, result: value.result,
|
|
159
|
-
runID: value.runId, status: value.status, replayed: value.replayed };
|
|
160
|
-
},
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
/** Uses configureClient()/TIER0_API_HOST/TIER0_API_KEY, resolved for every call. */
|
|
165
|
-
export const controls = new ControlsClient();
|
|
166
|
-
//# sourceMappingURL=controls.js.map
|
package/dist/esm/controls.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"controls.js","sourceRoot":"","sources":["../../src/controls.ts"],"names":[],"mappings":"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","sourcesContent":["import { getClient, type HttpClient, type ClientConfig } from './openapi/client.js';\nimport { DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS, type CloudTransportConfig } from './cloud-transport.js';\nimport { UnsV2ClientCore, UnsV2Error, type UnsV2Execution, type UnsV2Retry } from './uns-v2/client.js';\nimport { UnsV2RawNumber } from './uns-v2/codec.js';\nimport type { UnsV2JSONValue, UnsV2Request } from './uns-v2/generated.js';\n\n/** Control convenience API over the canonical UNS v2 routes. Exact numbers are preserved. */\nexport type ControlJSON = UnsV2JSONValue;\n\nexport interface PublicControl {\n code: string;\n name: string;\n description: string;\n contractVersion: string;\n inputSchema: Record<string, ControlJSON>;\n outputSchema: Record<string, ControlJSON>;\n sideEffect: 'read' | 'write';\n idempotency: 'none' | 'optional' | 'required';\n timeoutMs: number;\n status: string;\n}\n\nexport interface ControlDiscoverOptions {\n page?: number;\n size?: number;\n search?: string;\n}\n\nexport interface ControlDiscoverResponse {\n total: number;\n list: PublicControl[];\n}\n\n/** Shared HTTP settings. The server still resolves the Control binding and authorization. */\nexport interface ControlTransportConfig extends CloudTransportConfig {}\n\nexport interface CloudClientConfig extends ClientConfig, ControlTransportConfig {}\n\nexport const DEFAULT_CONTROL_TRANSPORT_TIMEOUT_MS = DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS;\n\nexport interface ControlInvokeOptions {\n /** Stable caller-owned key for one business intent, at most 128 UTF-8 bytes. Never generated or retried by the SDK. */\n idempotencyKey?: string;\n}\n\nexport interface ControlInvokeResponse<Result = ControlJSON> {\n code: string;\n contractVersion: string;\n result: Result;\n runID: string;\n status: string;\n /** True only when the server explicitly reports an idempotent replay. */\n replayed: boolean;\n}\n\nexport interface ControlErrorInfo {\n /** HTTP status, absent when no HTTP response was received. */\n status?: number;\n /** Canonical UNS error.code, or an SDK-local CONTROL_* transport/protocol code. */\n errorCode: string;\n runID?: string;\n contractVersion?: string;\n runStatus?: string;\n replayed?: boolean;\n requestId?: string;\n execution?: UnsV2Execution;\n retry?: UnsV2Retry;\n reason?: string;\n details?: Record<string, unknown>[];\n data?: unknown;\n}\n\n/** No Control error is automatically retried, including authentication failures. */\nexport class ControlError extends Error {\n readonly status?: number;\n readonly errorCode: string;\n readonly runID?: string;\n readonly contractVersion?: string;\n readonly runStatus?: string;\n readonly replayed?: boolean;\n readonly requestId?: string;\n readonly execution?: UnsV2Execution;\n readonly retry?: UnsV2Retry;\n readonly reason?: string;\n readonly details?: Record<string, unknown>[];\n readonly data?: unknown;\n readonly retryable = false;\n\n constructor(message: string, info: ControlErrorInfo) {\n super(message);\n this.name = 'ControlError';\n this.status = info.status;\n this.errorCode = info.errorCode;\n this.runID = info.runID;\n this.contractVersion = info.contractVersion;\n this.runStatus = info.runStatus;\n this.replayed = info.replayed;\n this.requestId = info.requestId;\n this.execution = info.execution;\n this.retry = info.retry;\n this.reason = info.reason;\n this.details = info.details;\n this.data = info.data;\n }\n}\n\n/** Execution may have happened. Reconcile run information; any deliberate replay must reuse the same key. */\nexport class ControlResultUnknownError extends ControlError {\n readonly outcomeUnknown = true;\n\n constructor(info: ControlErrorInfo) {\n super('Control result is unknown; execution may have occurred. Do not automatically retry.', info);\n this.name = 'ControlResultUnknownError';\n }\n}\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction keys(value: unknown, allowed: string[]): void {\n if (!record(value) || Reflect.ownKeys(value).some(key => typeof key !== 'string' || !allowed.includes(key))) {\n throw new TypeError('Tier0 SDK: unsupported Control option.');\n }\n}\n\nfunction json(value: unknown, seen = new Set<unknown>()): boolean {\n if (value === null || typeof value === 'string' || typeof value === 'boolean' || value instanceof UnsV2RawNumber) return true;\n if (typeof value === 'number') return Number.isFinite(value);\n if (typeof value !== 'object' || seen.has(value)) return false;\n if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {\n return false;\n }\n seen.add(value);\n const valid = (Array.isArray(value) ? Array.from(value) : Object.values(value)).every(item => json(item, seen));\n seen.delete(value);\n return valid;\n}\n\nfunction definition(value: unknown): value is PublicControl {\n if (!record(value)) return false;\n return ['code', 'name', 'description', 'contractVersion', 'status'].every(key => typeof value[key] === 'string') &&\n value.code !== '' && value.contractVersion !== '' && record(value.inputSchema) && record(value.outputSchema) &&\n ['read', 'write'].includes(value.sideEffect as string) &&\n ['none', 'optional', 'required'].includes(value.idempotency as string) &&\n typeof value.timeoutMs === 'number' && Number.isSafeInteger(value.timeoutMs) && value.timeoutMs > 0;\n}\n\nfunction runInfo(value: unknown): Partial<ControlErrorInfo> {\n if (!record(value)) return {};\n return {\n runID: typeof value.runId === 'string' ? value.runId : undefined,\n contractVersion: typeof value.contractVersion === 'string' ? value.contractVersion : undefined,\n runStatus: typeof value.status === 'string' ? value.status : undefined,\n replayed: typeof value.replayed === 'boolean' ? value.replayed : undefined,\n };\n}\n\nexport interface ControlHandle<Input = ControlJSON, Result = ControlJSON> {\n describe(): Promise<PublicControl>;\n /**\n * One POST only. Input is opaque business JSON, including fields named streamId,\n * entryId, deploymentVersion or timeoutMs. Only the server chooses binding/version/timeout.\n * Generic types are caller assertions; the server validates the contract schemas.\n */\n invoke(input: Input, options?: ControlInvokeOptions): Promise<ControlInvokeResponse<Result>>;\n}\n\nexport class ControlsClient {\n private readonly uns: UnsV2ClientCore;\n\n constructor(resolveClient: () => HttpClient = getClient, config: ControlTransportConfig = {}) {\n this.uns = new UnsV2ClientCore(resolveClient, config);\n }\n\n private async post<Name extends 'controlDiscover' | 'controlDescribe' | 'controlInvoke'>(\n operation: Name, body: UnsV2Request<Name>,\n ): Promise<{ value: unknown; status: number }> {\n try {\n const response = await this.uns.call(operation, body);\n return { value: response.data, status: 200 };\n } catch (error) {\n if (!(error instanceof UnsV2Error)) throw error;\n const info: ControlErrorInfo = {\n ...runInfo(error.data), status: error.status,\n errorCode: error.code.replace(/^UNS_V2_/, 'CONTROL_'),\n requestId: error.requestId, execution: error.execution, retry: error.retry,\n reason: error.reason, details: error.details, data: error.data,\n };\n if (error.outcomeUnknown) throw new ControlResultUnknownError(info);\n throw new ControlError(error.message, info);\n }\n }\n\n /** Discover visible contracts; defaults and authorization are resolved by the server. */\n async discover(options: ControlDiscoverOptions = {}): Promise<ControlDiscoverResponse> {\n keys(options, ['page', 'size', 'search']);\n if ((options.page !== undefined && (!Number.isSafeInteger(options.page) || options.page < 1)) ||\n (options.size !== undefined && (!Number.isSafeInteger(options.size) || options.size < 1 || options.size > 200)) ||\n (options.search !== undefined && typeof options.search !== 'string')) {\n throw new TypeError('Tier0 SDK: invalid Control discovery options.');\n }\n const { value, status } = await this.post('controlDiscover', options);\n if (!record(value) || !Number.isSafeInteger(value.total) || (value.total as number) < 0 ||\n !Array.isArray(value.list) || !value.list.every(definition)) {\n throw new ControlError('Invalid Control discovery response.', { status, errorCode: 'CONTROL_PROTOCOL_ERROR' });\n }\n return { total: value.total as number, list: value.list as PublicControl[] };\n }\n\n use<Input = ControlJSON, Result = ControlJSON>(selector: { code: string }): ControlHandle<Input, Result> {\n keys(selector, ['code']);\n const code = selector.code;\n if (typeof code !== 'string' || code.length > 128 || !/^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/.test(code)) {\n throw new TypeError('Tier0 SDK: invalid Control code.');\n }\n return {\n describe: async () => {\n const { value, status } = await this.post('controlDescribe', { code });\n if (!definition(value) || value.code !== code) {\n throw new ControlError('Invalid Control description.', { status, errorCode: 'CONTROL_PROTOCOL_ERROR' });\n }\n return value;\n },\n invoke: async (input, options = {}) => {\n keys(options, ['idempotencyKey']);\n const key = options.idempotencyKey;\n if (key !== undefined && (typeof key !== 'string' || !key || key.trim() !== key || new TextEncoder().encode(key).length > 128)) {\n throw new TypeError('Tier0 SDK: invalid Control idempotency key.');\n }\n if (!json(input)) throw new TypeError('Tier0 SDK: Control input must be JSON.');\n const { value, status } = await this.post('controlInvoke', {\n code, input: input as ControlJSON, ...(key === undefined ? {} : { idempotencyKey: key }),\n });\n if (!record(value) || value.code !== code || typeof value.contractVersion !== 'string' || !value.contractVersion ||\n !Object.prototype.hasOwnProperty.call(value, 'result') || typeof value.runId !== 'string' || !value.runId ||\n typeof value.status !== 'string' || !value.status || ['accepted', 'queued', 'pending', 'running'].includes(value.status) ||\n typeof value.replayed !== 'boolean') {\n throw new ControlResultUnknownError({ ...runInfo(value), status, errorCode: 'CONTROL_PROTOCOL_ERROR' });\n }\n return { code: value.code, contractVersion: value.contractVersion, result: value.result as Result,\n runID: value.runId, status: value.status, replayed: value.replayed };\n },\n };\n }\n}\n\n/** Uses configureClient()/TIER0_API_HOST/TIER0_API_KEY, resolved for every call. */\nexport const controls = new ControlsClient();\n"]}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: tier0-sdk-v2-controls
|
|
3
|
-
description: 使用 @tier0/sdk-v2 发现、描述和调用 Tier0 Control 业务契约,区分读写副作用、契约版本、幂等要求和执行结果未知。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Control 契约调用
|
|
7
|
-
|
|
8
|
-
Control 是已发布的业务调用入口;它可由 Stream 提供,但调用方不选择内部 streamId、entryId 或部署版本。使用服务端 client.controls,实际调用 `/openapi/v2/uns/controls/discover|describe|invoke`。
|
|
9
|
-
|
|
10
|
-
调用按服务端现有统一权限及 App 业务策略校验;不配置逐 Key 的 Control scopes/codes。
|
|
11
|
-
|
|
12
|
-
## 发现和读取契约
|
|
13
|
-
|
|
14
|
-
```ts
|
|
15
|
-
import { createClient } from '@tier0/sdk-v2';
|
|
16
|
-
|
|
17
|
-
export async function discoverControls(search: string) {
|
|
18
|
-
return createClient().controls.discover({ search, page: 1, size: 20 });
|
|
19
|
-
}
|
|
20
|
-
export async function describeControl(code: string) {
|
|
21
|
-
return createClient().controls.use({ code }).describe();
|
|
22
|
-
}
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
discover 返回 total/list,分页从 1 开始,size 为 1–200。code 取自发现结果,不由显示名称猜测。describe 返回 inputSchema、outputSchema、sideEffect、idempotency、contractVersion、timeoutMs 和 status。
|
|
26
|
-
|
|
27
|
-
## 构造调用
|
|
28
|
-
|
|
29
|
-
1. 依据 inputSchema 填写输入,业务 JSON 不等于任意控制参数。SDK 的泛型只提供静态提示,不能替代契约校验。
|
|
30
|
-
2. 判断 sideEffect=read/write,与用户本次任务的授权范围一致。
|
|
31
|
-
3. 当 idempotency=required 时提供稳定的业务意图键;optional/none 按契约决定,不自动生成 UUID 重试。
|
|
32
|
-
4. 调用后检查业务 result 与 status,记录 runID/contractVersion,不能只看请求未抛错。
|
|
33
|
-
|
|
34
|
-
```ts
|
|
35
|
-
import {
|
|
36
|
-
createClient, ControlResultUnknownError, type ControlJSON,
|
|
37
|
-
} from '@tier0/sdk-v2';
|
|
38
|
-
|
|
39
|
-
export async function invokePreparedControl(code: string, input: ControlJSON, intentKey?: string) {
|
|
40
|
-
const handle = createClient().controls.use({ code });
|
|
41
|
-
const definition = await handle.describe();
|
|
42
|
-
if (definition.idempotency === 'required' && !intentKey) {
|
|
43
|
-
throw new Error('该 Control 要求业务幂等键');
|
|
44
|
-
}
|
|
45
|
-
// 调用方已经按 definition.inputSchema 校验输入,并确认本次业务意图。
|
|
46
|
-
try {
|
|
47
|
-
return await handle.invoke(input, intentKey ? { idempotencyKey: intentKey } : {});
|
|
48
|
-
} catch (error) {
|
|
49
|
-
if (error instanceof ControlResultUnknownError) {
|
|
50
|
-
return { outcomeUnknown: true as const, runID: error.runID, errorCode: error.errorCode };
|
|
51
|
-
}
|
|
52
|
-
throw error;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
幂等键非空、不能有首尾空白,最多 128 UTF-8 字节。输入使用 JSON;需要保留精确数字时可用 UnsV2RawNumber,不传 Date、函数、循环对象、bigint、NaN/Infinity。业务 input 内名为 timeoutMs/streamId 的字段仍只是业务输入;不能借它覆盖服务端绑定、版本或执行超时。
|
|
58
|
-
|
|
59
|
-
## 返回与失败
|
|
60
|
-
|
|
61
|
-
成功值为直接对象:code(Control 标识)、contractVersion、result、runID、status、replayed。这里的 code 不是 HTTP 业务状态码;replayed 只有服务端明确报告重放时才为 true。
|
|
62
|
-
|
|
63
|
-
`ControlError` 含 status/errorCode/runID 与 requestId/execution/retry 等信息,SDK 不自动重试。`ControlResultUnknownError` 表示执行可能已经发生,包括调用响应无法证明最终结果的情况;按业务或平台运行记录对账。本 SDK 未提供通用 `controls.getRun`,不要虚构方法。若业务明确允许重放,保留原 key 和原输入,不能换新 key 重做。
|
|
64
|
-
|
|
65
|
-
`client.capabilities.discover()` 的 control.invoke.v1 就绪只是入口条件,不等于有权调用每一个 Control。执行源发布和内部绑定管理请使用 [Stream Skill](../tier0-sdk-v2-stream/SKILL.md)。
|