@runtypelabs/sdk 9.9.0 → 9.10.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/dist/index.cjs +769 -656
- package/dist/index.d.cts +2281 -812
- package/dist/index.d.ts +2281 -812
- package/dist/index.mjs +767 -656
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -37,6 +37,7 @@ var UNIFIED_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
37
37
|
"approval_complete",
|
|
38
38
|
"await",
|
|
39
39
|
"error",
|
|
40
|
+
"context_notice",
|
|
40
41
|
"ping",
|
|
41
42
|
"custom"
|
|
42
43
|
]);
|
|
@@ -2635,11 +2636,12 @@ async function request(client, body) {
|
|
|
2635
2636
|
}
|
|
2636
2637
|
}
|
|
2637
2638
|
async function ensureFlow(client, definition, options = {}) {
|
|
2638
|
-
const { dryRun, onConflict, release, expectedRemoteHash, expectNoChanges } = options;
|
|
2639
|
+
const { dryRun, onConflict, release, expectedRemoteHash, version, expectNoChanges } = options;
|
|
2639
2640
|
const passthrough = {
|
|
2640
2641
|
...onConflict ? { onConflict } : {},
|
|
2641
2642
|
...release ? { release } : {},
|
|
2642
|
-
...expectedRemoteHash ? { expectedRemoteHash } : {}
|
|
2643
|
+
...expectedRemoteHash ? { expectedRemoteHash } : {},
|
|
2644
|
+
...version ? { version } : {}
|
|
2643
2645
|
};
|
|
2644
2646
|
const wireDefinition = { name: definition.name, steps: definition.steps };
|
|
2645
2647
|
if (dryRun || expectNoChanges) {
|
|
@@ -4915,11 +4917,12 @@ var AgentsNamespace = class {
|
|
|
4915
4917
|
*/
|
|
4916
4918
|
async ensure(definition, options = {}) {
|
|
4917
4919
|
const client = this.getClient();
|
|
4918
|
-
const { dryRun, onConflict, release, expectedRemoteHash, expectNoChanges } = options;
|
|
4920
|
+
const { dryRun, onConflict, release, expectedRemoteHash, version, expectNoChanges } = options;
|
|
4919
4921
|
const passthrough = {
|
|
4920
4922
|
...onConflict ? { onConflict } : {},
|
|
4921
4923
|
...release ? { release } : {},
|
|
4922
|
-
...expectedRemoteHash ? { expectedRemoteHash } : {}
|
|
4924
|
+
...expectedRemoteHash ? { expectedRemoteHash } : {},
|
|
4925
|
+
...version ? { version } : {}
|
|
4923
4926
|
};
|
|
4924
4927
|
if (dryRun || expectNoChanges) {
|
|
4925
4928
|
const plan = await this.request(client, {
|
|
@@ -5766,542 +5769,51 @@ function normalizeDispatchRequest(request6) {
|
|
|
5766
5769
|
return request6.flow ? { ...normalized, flow: request6.flow } : { ...normalized, agent: request6.agent };
|
|
5767
5770
|
}
|
|
5768
5771
|
|
|
5769
|
-
// src/
|
|
5770
|
-
var
|
|
5771
|
-
var
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
this.headers.Authorization = `Bearer ${config.apiKey}`;
|
|
5784
|
-
}
|
|
5785
|
-
}
|
|
5786
|
-
/**
|
|
5787
|
-
* Set the API key for authentication
|
|
5788
|
-
*/
|
|
5789
|
-
setApiKey(apiKey) {
|
|
5790
|
-
this.headers.Authorization = `Bearer ${apiKey}`;
|
|
5791
|
-
}
|
|
5792
|
-
/**
|
|
5793
|
-
* Generic GET request
|
|
5794
|
-
*/
|
|
5795
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts typed list-param interfaces (no index signature); `unknown` would reject them
|
|
5796
|
-
async get(path, params) {
|
|
5797
|
-
const url = this.buildUrl(path, params);
|
|
5798
|
-
const response = await this.makeRequest(url, {
|
|
5799
|
-
method: "GET",
|
|
5800
|
-
headers: this.headers
|
|
5801
|
-
});
|
|
5802
|
-
return response;
|
|
5803
|
-
}
|
|
5804
|
-
/**
|
|
5805
|
-
* Generic POST request
|
|
5806
|
-
*/
|
|
5807
|
-
async post(path, data, extraHeaders) {
|
|
5808
|
-
const url = this.buildUrl(path);
|
|
5809
|
-
const response = await this.makeRequest(url, {
|
|
5810
|
-
method: "POST",
|
|
5811
|
-
headers: { ...this.headers, ...extraHeaders },
|
|
5812
|
-
body: data ? JSON.stringify(data) : void 0
|
|
5813
|
-
});
|
|
5814
|
-
return response;
|
|
5815
|
-
}
|
|
5816
|
-
/**
|
|
5817
|
-
* Generic PUT request
|
|
5818
|
-
*/
|
|
5819
|
-
async put(path, data) {
|
|
5820
|
-
const url = this.buildUrl(path);
|
|
5821
|
-
const response = await this.makeRequest(url, {
|
|
5822
|
-
method: "PUT",
|
|
5823
|
-
headers: this.headers,
|
|
5824
|
-
body: data ? JSON.stringify(data) : void 0
|
|
5825
|
-
});
|
|
5826
|
-
return response;
|
|
5827
|
-
}
|
|
5828
|
-
/**
|
|
5829
|
-
* Generic PATCH request
|
|
5830
|
-
*/
|
|
5831
|
-
async patch(path, data) {
|
|
5832
|
-
const url = this.buildUrl(path);
|
|
5833
|
-
const response = await this.makeRequest(url, {
|
|
5834
|
-
method: "PATCH",
|
|
5835
|
-
headers: this.headers,
|
|
5836
|
-
body: data ? JSON.stringify(data) : void 0
|
|
5837
|
-
});
|
|
5838
|
-
return response;
|
|
5839
|
-
}
|
|
5840
|
-
/**
|
|
5841
|
-
* Generic DELETE request
|
|
5842
|
-
*/
|
|
5843
|
-
async delete(path) {
|
|
5844
|
-
const url = this.buildUrl(path);
|
|
5845
|
-
const response = await this.makeRequest(url, {
|
|
5846
|
-
method: "DELETE",
|
|
5847
|
-
headers: this.headers
|
|
5848
|
-
});
|
|
5849
|
-
return response;
|
|
5850
|
-
}
|
|
5851
|
-
/**
|
|
5852
|
-
* Generic request that returns raw Response for streaming
|
|
5853
|
-
*/
|
|
5854
|
-
async requestStream(path, options = {}) {
|
|
5855
|
-
const url = this.buildUrl(path);
|
|
5856
|
-
const headers = {
|
|
5857
|
-
...this.headers,
|
|
5858
|
-
...options.headers
|
|
5859
|
-
};
|
|
5860
|
-
return this.makeRawRequest(url, {
|
|
5861
|
-
...options,
|
|
5862
|
-
headers
|
|
5863
|
-
});
|
|
5864
|
-
}
|
|
5865
|
-
/**
|
|
5866
|
-
* Dispatch flow execution (streaming).
|
|
5867
|
-
*
|
|
5868
|
-
* This is the sole streaming-dispatch chokepoint for the flow builders
|
|
5869
|
-
* (`RuntypeFlowBuilder`), so it normalizes the request to the canonical
|
|
5870
|
-
* `/v1/dispatch` wire contract here — every builder path inherits the same
|
|
5871
|
-
* normalization the `DispatchEndpoint` applies, with no per-builder call.
|
|
5872
|
-
*/
|
|
5873
|
-
async dispatch(config) {
|
|
5874
|
-
const normalized = normalizeDispatchRequest(config);
|
|
5875
|
-
const request6 = {
|
|
5876
|
-
...normalized,
|
|
5877
|
-
options: {
|
|
5878
|
-
...normalized.options,
|
|
5879
|
-
streamResponse: true
|
|
5880
|
-
}
|
|
5881
|
-
};
|
|
5882
|
-
return this.requestStream("/dispatch", {
|
|
5883
|
-
method: "POST",
|
|
5884
|
-
body: JSON.stringify(request6)
|
|
5885
|
-
});
|
|
5886
|
-
}
|
|
5887
|
-
/**
|
|
5888
|
-
* Dispatch flow execution (non-streaming JSON).
|
|
5889
|
-
*
|
|
5890
|
-
* The non-streaming sibling of {@link dispatch}; it normalizes to the same
|
|
5891
|
-
* canonical wire contract so builders never post a raw, un-normalized body,
|
|
5892
|
-
* and pins `streamResponse: false` so the server returns buffered JSON.
|
|
5893
|
-
*/
|
|
5894
|
-
async dispatchJson(config) {
|
|
5895
|
-
const normalized = normalizeDispatchRequest(config);
|
|
5896
|
-
return this.post("/dispatch", {
|
|
5897
|
-
...normalized,
|
|
5898
|
-
options: {
|
|
5899
|
-
...normalized.options,
|
|
5900
|
-
streamResponse: false
|
|
5901
|
-
}
|
|
5902
|
-
});
|
|
5903
|
-
}
|
|
5904
|
-
/** Start a normalized dispatch and return a durable handle immediately. */
|
|
5905
|
-
async dispatchAsync(config) {
|
|
5906
|
-
const normalized = normalizeDispatchRequest(config);
|
|
5907
|
-
return this.post(
|
|
5908
|
-
"/dispatch",
|
|
5909
|
-
{
|
|
5910
|
-
...normalized,
|
|
5911
|
-
options: { ...normalized.options, streamResponse: false }
|
|
5912
|
-
},
|
|
5913
|
-
{ Prefer: "respond-async" }
|
|
5914
|
-
);
|
|
5915
|
-
}
|
|
5916
|
-
async getExecutionStatus(executionId) {
|
|
5917
|
-
return this.get(`/executions/${encodeURIComponent(executionId)}/status`);
|
|
5918
|
-
}
|
|
5919
|
-
/**
|
|
5920
|
-
* Build full URL with query parameters
|
|
5921
|
-
*/
|
|
5922
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- mirrors get()'s permissive params type
|
|
5923
|
-
buildUrl(path, params) {
|
|
5924
|
-
const base = this.baseUrl.endsWith("/") ? this.baseUrl : `${this.baseUrl}/`;
|
|
5925
|
-
const relPath = path.startsWith("/") ? path.slice(1) : path;
|
|
5926
|
-
const url = new URL(relPath, base);
|
|
5927
|
-
if (params) {
|
|
5928
|
-
Object.entries(params).forEach(([key, value]) => {
|
|
5929
|
-
if (value !== void 0 && value !== null) {
|
|
5930
|
-
url.searchParams.set(key, String(value));
|
|
5931
|
-
}
|
|
5932
|
-
});
|
|
5772
|
+
// src/detached-reconnect.ts
|
|
5773
|
+
var TERMINAL_EVENTS = /* @__PURE__ */ new Set(["execution_complete", "execution_error"]);
|
|
5774
|
+
var DEFAULT_MAX_DETACHED_RECONNECTS = 12;
|
|
5775
|
+
function combineAbortSignals(...signals) {
|
|
5776
|
+
const present = signals.filter((signal) => Boolean(signal));
|
|
5777
|
+
if (present.length === 0) return void 0;
|
|
5778
|
+
if (present.length === 1) return present[0];
|
|
5779
|
+
const anySignal = AbortSignal.any;
|
|
5780
|
+
if (typeof anySignal === "function") return anySignal.call(AbortSignal, present);
|
|
5781
|
+
const controller = new AbortController();
|
|
5782
|
+
for (const signal of present) {
|
|
5783
|
+
if (signal.aborted) {
|
|
5784
|
+
controller.abort(signal.reason);
|
|
5785
|
+
break;
|
|
5933
5786
|
}
|
|
5934
|
-
|
|
5787
|
+
signal.addEventListener("abort", () => controller.abort(signal.reason), { once: true });
|
|
5935
5788
|
}
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
if (
|
|
5942
|
-
|
|
5789
|
+
return controller.signal;
|
|
5790
|
+
}
|
|
5791
|
+
function observeBlock(block, into) {
|
|
5792
|
+
let eventName = null;
|
|
5793
|
+
for (const line of block.split("\n")) {
|
|
5794
|
+
if (line.startsWith("id:")) {
|
|
5795
|
+
into.lastId = line.slice(3).trim();
|
|
5796
|
+
continue;
|
|
5943
5797
|
}
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5798
|
+
if (line.startsWith("event:")) {
|
|
5799
|
+
eventName = line.slice(6).trim();
|
|
5800
|
+
continue;
|
|
5947
5801
|
}
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
*/
|
|
5953
|
-
async makeRawRequest(url, options) {
|
|
5954
|
-
const controller = new AbortController();
|
|
5955
|
-
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
5802
|
+
if (!line.startsWith("data:")) continue;
|
|
5803
|
+
const raw = line.slice(5).trim();
|
|
5804
|
+
if (!raw || raw === "[DONE]") continue;
|
|
5805
|
+
let payload;
|
|
5956
5806
|
try {
|
|
5957
|
-
const
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
if (!response.ok) {
|
|
5963
|
-
const errorText = await response.text();
|
|
5964
|
-
throw new Error(
|
|
5965
|
-
`API request failed: ${response.status} ${response.statusText} - ${errorText}`
|
|
5966
|
-
);
|
|
5967
|
-
}
|
|
5968
|
-
return response;
|
|
5969
|
-
} catch (error) {
|
|
5970
|
-
clearTimeout(timeoutId);
|
|
5971
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
5972
|
-
throw new Error(`Request timeout after ${this.timeout}ms`, { cause: error });
|
|
5973
|
-
}
|
|
5974
|
-
throw error;
|
|
5975
|
-
}
|
|
5976
|
-
}
|
|
5977
|
-
};
|
|
5978
|
-
var Runtype = class {
|
|
5979
|
-
/**
|
|
5980
|
-
* Configure the global Runtype client
|
|
5981
|
-
*
|
|
5982
|
-
* Call this once at app startup to set the API key and other options.
|
|
5983
|
-
* All subsequent calls to Runtype.flows, Runtype.batches, etc. will use this config.
|
|
5984
|
-
*
|
|
5985
|
-
* @example
|
|
5986
|
-
* ```typescript
|
|
5987
|
-
* Runtype.configure({ apiKey: process.env.RUNTYPE_API_KEY })
|
|
5988
|
-
* ```
|
|
5989
|
-
*/
|
|
5990
|
-
static configure(config) {
|
|
5991
|
-
globalConfig = { ...globalConfig, ...config };
|
|
5992
|
-
globalClient = new RuntypeClient(globalConfig);
|
|
5993
|
-
}
|
|
5994
|
-
/**
|
|
5995
|
-
* Get the global client instance, creating one if needed
|
|
5996
|
-
*/
|
|
5997
|
-
static getClient() {
|
|
5998
|
-
if (!globalClient) {
|
|
5999
|
-
globalClient = new RuntypeClient(globalConfig);
|
|
5807
|
+
const parsed = JSON.parse(raw);
|
|
5808
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) continue;
|
|
5809
|
+
payload = parsed;
|
|
5810
|
+
} catch {
|
|
5811
|
+
continue;
|
|
6000
5812
|
}
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
*
|
|
6006
|
-
* Use this when you need a client with different settings than the global one.
|
|
6007
|
-
*
|
|
6008
|
-
* @example
|
|
6009
|
-
* ```typescript
|
|
6010
|
-
* const client = Runtype.createClient({ apiKey: 'different_key' })
|
|
6011
|
-
* ```
|
|
6012
|
-
*/
|
|
6013
|
-
static createClient(config) {
|
|
6014
|
-
return new RuntypeClient({ ...globalConfig, ...config });
|
|
6015
|
-
}
|
|
6016
|
-
/**
|
|
6017
|
-
* Flows namespace - Build and execute flows
|
|
6018
|
-
*
|
|
6019
|
-
* @example
|
|
6020
|
-
* ```typescript
|
|
6021
|
-
* // Upsert a flow (create or update)
|
|
6022
|
-
* const result = await Runtype.flows.upsert({ name: 'My Flow' })
|
|
6023
|
-
* .prompt({ name: 'Analyze', model: 'gpt-4o', userPrompt: '...' })
|
|
6024
|
-
* .stream()
|
|
6025
|
-
*
|
|
6026
|
-
* // Use an existing flow
|
|
6027
|
-
* const result = await Runtype.flows.use('flow_123')
|
|
6028
|
-
* .withRecord({ name: 'Test' })
|
|
6029
|
-
* .result()
|
|
6030
|
-
*
|
|
6031
|
-
* // Virtual flow (one-off, not saved)
|
|
6032
|
-
* const result = await Runtype.flows.virtual({ name: 'Temp Flow' })
|
|
6033
|
-
* .prompt({ ... })
|
|
6034
|
-
* .stream()
|
|
6035
|
-
* ```
|
|
6036
|
-
*/
|
|
6037
|
-
static get flows() {
|
|
6038
|
-
return new FlowsNamespace(() => this.getClient());
|
|
6039
|
-
}
|
|
6040
|
-
/**
|
|
6041
|
-
* Batches namespace - Schedule and manage batch operations
|
|
6042
|
-
*
|
|
6043
|
-
* @example
|
|
6044
|
-
* ```typescript
|
|
6045
|
-
* // Schedule a batch
|
|
6046
|
-
* const batch = await Runtype.batches.schedule({
|
|
6047
|
-
* flowId: 'flow_123',
|
|
6048
|
-
* recordType: 'customers',
|
|
6049
|
-
* })
|
|
6050
|
-
*
|
|
6051
|
-
* // Get batch status
|
|
6052
|
-
* const status = await Runtype.batches.get('batch_456')
|
|
6053
|
-
*
|
|
6054
|
-
* // Cancel a batch
|
|
6055
|
-
* await Runtype.batches.cancel('batch_456')
|
|
6056
|
-
*
|
|
6057
|
-
* // List batches
|
|
6058
|
-
* const batches = await Runtype.batches.list({ status: 'running' })
|
|
6059
|
-
* ```
|
|
6060
|
-
*/
|
|
6061
|
-
static get batches() {
|
|
6062
|
-
return new BatchesNamespace(() => this.getClient());
|
|
6063
|
-
}
|
|
6064
|
-
/**
|
|
6065
|
-
* Evals namespace - Run evaluations and compare models
|
|
6066
|
-
*
|
|
6067
|
-
* @example
|
|
6068
|
-
* ```typescript
|
|
6069
|
-
* // Run an eval with streaming
|
|
6070
|
-
* const stream = await Runtype.evals.run({
|
|
6071
|
-
* flowId: 'flow_123',
|
|
6072
|
-
* recordType: 'test_data',
|
|
6073
|
-
* models: [{ stepName: 'Analyze', model: 'gpt-4o' }]
|
|
6074
|
-
* }).stream()
|
|
6075
|
-
*
|
|
6076
|
-
* // Submit eval as batch job
|
|
6077
|
-
* const eval = await Runtype.evals.run({
|
|
6078
|
-
* flowId: 'flow_123',
|
|
6079
|
-
* recordType: 'test_data',
|
|
6080
|
-
* models: [
|
|
6081
|
-
* [{ stepName: 'Analyze', model: 'gpt-5.4' }],
|
|
6082
|
-
* [{ stepName: 'Analyze', model: 'claude-opus-4-6' }],
|
|
6083
|
-
* ]
|
|
6084
|
-
* }).submit()
|
|
6085
|
-
* ```
|
|
6086
|
-
*/
|
|
6087
|
-
static get evals() {
|
|
6088
|
-
return new EvalsNamespace(() => this.getClient());
|
|
6089
|
-
}
|
|
6090
|
-
/**
|
|
6091
|
-
* Prompts namespace - Manage and execute prompts
|
|
6092
|
-
*
|
|
6093
|
-
* @example
|
|
6094
|
-
* ```typescript
|
|
6095
|
-
* // Execute a prompt with streaming
|
|
6096
|
-
* const stream = await Runtype.prompts.run('prompt_123', {
|
|
6097
|
-
* recordId: 'rec_456'
|
|
6098
|
-
* }).stream()
|
|
6099
|
-
*
|
|
6100
|
-
* // Get complete result
|
|
6101
|
-
* const result = await Runtype.prompts.run('prompt_123', {
|
|
6102
|
-
* recordId: 'rec_456'
|
|
6103
|
-
* }).result()
|
|
6104
|
-
*
|
|
6105
|
-
* // CRUD operations
|
|
6106
|
-
* const prompts = await Runtype.prompts.list()
|
|
6107
|
-
* const prompt = await Runtype.prompts.get('prompt_123')
|
|
6108
|
-
* const newPrompt = await Runtype.prompts.create({ ... })
|
|
6109
|
-
* await Runtype.prompts.update('prompt_123', { ... })
|
|
6110
|
-
* await Runtype.prompts.delete('prompt_123')
|
|
6111
|
-
* ```
|
|
6112
|
-
*/
|
|
6113
|
-
static get prompts() {
|
|
6114
|
-
return new PromptsNamespace(() => this.getClient());
|
|
6115
|
-
}
|
|
6116
|
-
/**
|
|
6117
|
-
* Skills namespace - Manage Agent Skills (admin/control plane)
|
|
6118
|
-
*
|
|
6119
|
-
* @example
|
|
6120
|
-
* ```typescript
|
|
6121
|
-
* // Create a published skill from a SKILL.md document
|
|
6122
|
-
* const { skill } = await Runtype.skills.create({ markdown: skillMd, publish: true })
|
|
6123
|
-
*
|
|
6124
|
-
* // Bind it to an agent
|
|
6125
|
-
* await Runtype.skills.bind({ agentId: 'agent_123', skillId: skill.id })
|
|
6126
|
-
*
|
|
6127
|
-
* // Review agent-authored proposals
|
|
6128
|
-
* const pending = await Runtype.skills.proposals.list()
|
|
6129
|
-
* await Runtype.skills.proposals.approve(pending[0].id)
|
|
6130
|
-
* ```
|
|
6131
|
-
*/
|
|
6132
|
-
static get skills() {
|
|
6133
|
-
return new SkillsNamespace(() => this.getClient());
|
|
6134
|
-
}
|
|
6135
|
-
/**
|
|
6136
|
-
* Agents namespace - Agent config-as-code (define / ensure / pull)
|
|
6137
|
-
*
|
|
6138
|
-
* @example
|
|
6139
|
-
* ```typescript
|
|
6140
|
-
* import { defineAgent, Runtype } from '@runtypelabs/sdk'
|
|
6141
|
-
*
|
|
6142
|
-
* const assistant = defineAgent({
|
|
6143
|
-
* name: 'Pricing Assistant',
|
|
6144
|
-
* model: 'claude-sonnet-4-6',
|
|
6145
|
-
* systemPrompt: renderPrompt(pricingData),
|
|
6146
|
-
* })
|
|
6147
|
-
*
|
|
6148
|
-
* // Converge at deploy time (idempotent; one tiny probe in steady state)
|
|
6149
|
-
* await Runtype.agents.ensure(assistant)
|
|
6150
|
-
*
|
|
6151
|
-
* // CI drift gate
|
|
6152
|
-
* await Runtype.agents.ensure(assistant, { expectNoChanges: true })
|
|
6153
|
-
*
|
|
6154
|
-
* // Absorb a dashboard edit back into the repo
|
|
6155
|
-
* const { definition } = await Runtype.agents.pull('Pricing Assistant')
|
|
6156
|
-
* ```
|
|
6157
|
-
*/
|
|
6158
|
-
static get agents() {
|
|
6159
|
-
return new AgentsNamespace(() => this.getClient());
|
|
6160
|
-
}
|
|
6161
|
-
/** Poll durable handles returned by asynchronous execute operations. */
|
|
6162
|
-
static get executions() {
|
|
6163
|
-
return new ExecutionsNamespace(() => this.getClient());
|
|
6164
|
-
}
|
|
6165
|
-
/**
|
|
6166
|
-
* Tools namespace - Tool config-as-code (define / ensure / pull)
|
|
6167
|
-
*
|
|
6168
|
-
* @example
|
|
6169
|
-
* ```typescript
|
|
6170
|
-
* import { defineTool, Runtype } from '@runtypelabs/sdk'
|
|
6171
|
-
*
|
|
6172
|
-
* const weather = defineTool({
|
|
6173
|
-
* name: 'Weather Lookup',
|
|
6174
|
-
* description: 'Fetch the current weather for a city',
|
|
6175
|
-
* toolType: 'external',
|
|
6176
|
-
* parametersSchema: { type: 'object', properties: { city: { type: 'string' } } },
|
|
6177
|
-
* config: { url: 'https://api.example.com/weather', method: 'GET' },
|
|
6178
|
-
* })
|
|
6179
|
-
*
|
|
6180
|
-
* // Converge at deploy time (idempotent; one tiny probe in steady state)
|
|
6181
|
-
* await Runtype.tools.ensure(weather)
|
|
6182
|
-
*
|
|
6183
|
-
* // CI drift gate
|
|
6184
|
-
* await Runtype.tools.ensure(weather, { expectNoChanges: true })
|
|
6185
|
-
*
|
|
6186
|
-
* // Absorb a dashboard edit back into the repo
|
|
6187
|
-
* const { definition } = await Runtype.tools.pull('Weather Lookup')
|
|
6188
|
-
* ```
|
|
6189
|
-
*/
|
|
6190
|
-
static get tools() {
|
|
6191
|
-
return new ToolsNamespace(() => this.getClient());
|
|
6192
|
-
}
|
|
6193
|
-
/**
|
|
6194
|
-
* Products namespace - Product config-as-code (define / ensure / pull)
|
|
6195
|
-
*
|
|
6196
|
-
* Converges the top-level product record (description, icon, spec). Nested
|
|
6197
|
-
* capabilities/surfaces/tools and the canvas UI layout state are not
|
|
6198
|
-
* converged by ensure.
|
|
6199
|
-
*
|
|
6200
|
-
* @example
|
|
6201
|
-
* ```typescript
|
|
6202
|
-
* import { defineProduct, Runtype } from '@runtypelabs/sdk'
|
|
6203
|
-
*
|
|
6204
|
-
* const product = defineProduct({
|
|
6205
|
-
* name: 'Support Copilot',
|
|
6206
|
-
* description: 'An AI support assistant',
|
|
6207
|
-
* icon: '🤖',
|
|
6208
|
-
* spec: { productGoal: 'Deflect tier-1 tickets', productStage: 'beta' },
|
|
6209
|
-
* })
|
|
6210
|
-
*
|
|
6211
|
-
* // Converge at deploy time (idempotent; one tiny probe in steady state)
|
|
6212
|
-
* await Runtype.products.ensure(product)
|
|
6213
|
-
*
|
|
6214
|
-
* // CI drift gate
|
|
6215
|
-
* await Runtype.products.ensure(product, { expectNoChanges: true })
|
|
6216
|
-
*
|
|
6217
|
-
* // Absorb a dashboard edit back into the repo
|
|
6218
|
-
* const { definition } = await Runtype.products.pull('Support Copilot')
|
|
6219
|
-
* ```
|
|
6220
|
-
*/
|
|
6221
|
-
static get products() {
|
|
6222
|
-
return new ProductsNamespace(() => this.getClient());
|
|
6223
|
-
}
|
|
6224
|
-
/**
|
|
6225
|
-
* Config-as-code operations for product surfaces. `surfaces.ensure` is the
|
|
6226
|
-
* deploy-time, non-executing converge (create-or-update a surface by name
|
|
6227
|
-
* within a product); `surfaces.pull` is the absorb-drift direction.
|
|
6228
|
-
*
|
|
6229
|
-
* @example
|
|
6230
|
-
* ```typescript
|
|
6231
|
-
* import { Runtype, defineSurface } from '@runtypelabs/sdk'
|
|
6232
|
-
*
|
|
6233
|
-
* const chat = defineSurface({
|
|
6234
|
-
* name: 'Support Chat',
|
|
6235
|
-
* type: 'chat',
|
|
6236
|
-
* behavior: { type: 'chat', greeting: 'Hi there!' },
|
|
6237
|
-
* status: 'active',
|
|
6238
|
-
* })
|
|
6239
|
-
*
|
|
6240
|
-
* // Converge at deploy time (idempotent; one tiny probe in steady state)
|
|
6241
|
-
* await Runtype.surfaces.ensure('product_abc', chat)
|
|
6242
|
-
*
|
|
6243
|
-
* // CI drift gate
|
|
6244
|
-
* await Runtype.surfaces.ensure('product_abc', chat, { expectNoChanges: true })
|
|
6245
|
-
*
|
|
6246
|
-
* // Absorb a dashboard edit back into the repo
|
|
6247
|
-
* const { definition } = await Runtype.surfaces.pull('product_abc', 'Support Chat')
|
|
6248
|
-
* ```
|
|
6249
|
-
*/
|
|
6250
|
-
static get surfaces() {
|
|
6251
|
-
return new SurfacesNamespace(() => this.getClient());
|
|
6252
|
-
}
|
|
6253
|
-
};
|
|
6254
|
-
|
|
6255
|
-
// src/transform.ts
|
|
6256
|
-
function transformQueryParams(params) {
|
|
6257
|
-
const result = {};
|
|
6258
|
-
for (const [key, value] of Object.entries(params)) {
|
|
6259
|
-
if (value !== void 0 && value !== null) {
|
|
6260
|
-
if (Array.isArray(value)) {
|
|
6261
|
-
result[key] = value.join(",");
|
|
6262
|
-
} else {
|
|
6263
|
-
result[key] = String(value);
|
|
6264
|
-
}
|
|
6265
|
-
}
|
|
6266
|
-
}
|
|
6267
|
-
return result;
|
|
6268
|
-
}
|
|
6269
|
-
|
|
6270
|
-
// src/version.ts
|
|
6271
|
-
var FALLBACK_VERSION = "0.0.0";
|
|
6272
|
-
var SDK_VERSION = "9.9.0".length > 0 ? "9.9.0" : FALLBACK_VERSION;
|
|
6273
|
-
var RUNTYPE_CLIENT_KIND = "sdk";
|
|
6274
|
-
var SDK_USER_AGENT = `runtype-sdk/${SDK_VERSION} (typescript)`;
|
|
6275
|
-
|
|
6276
|
-
// src/detached-reconnect.ts
|
|
6277
|
-
var TERMINAL_EVENTS = /* @__PURE__ */ new Set(["execution_complete", "execution_error"]);
|
|
6278
|
-
var DEFAULT_MAX_DETACHED_RECONNECTS = 12;
|
|
6279
|
-
function observeBlock(block, into) {
|
|
6280
|
-
let eventName = null;
|
|
6281
|
-
for (const line of block.split("\n")) {
|
|
6282
|
-
if (line.startsWith("id:")) {
|
|
6283
|
-
into.lastId = line.slice(3).trim();
|
|
6284
|
-
continue;
|
|
6285
|
-
}
|
|
6286
|
-
if (line.startsWith("event:")) {
|
|
6287
|
-
eventName = line.slice(6).trim();
|
|
6288
|
-
continue;
|
|
6289
|
-
}
|
|
6290
|
-
if (!line.startsWith("data:")) continue;
|
|
6291
|
-
const raw = line.slice(5).trim();
|
|
6292
|
-
if (!raw || raw === "[DONE]") continue;
|
|
6293
|
-
let payload;
|
|
6294
|
-
try {
|
|
6295
|
-
const parsed = JSON.parse(raw);
|
|
6296
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) continue;
|
|
6297
|
-
payload = parsed;
|
|
6298
|
-
} catch {
|
|
6299
|
-
continue;
|
|
6300
|
-
}
|
|
6301
|
-
if (typeof payload.executionId === "string") into.executionId = payload.executionId;
|
|
6302
|
-
const type = typeof payload.type === "string" ? payload.type : eventName;
|
|
6303
|
-
if (type && TERMINAL_EVENTS.has(type)) into.sawTerminal = true;
|
|
6304
|
-
if (type === "await" && payload.awaitReason === "detached") into.sawDetach = true;
|
|
5813
|
+
if (typeof payload.executionId === "string") into.executionId = payload.executionId;
|
|
5814
|
+
const type = typeof payload.type === "string" ? payload.type : eventName;
|
|
5815
|
+
if (type && TERMINAL_EVENTS.has(type)) into.sawTerminal = true;
|
|
5816
|
+
if (type === "await" && payload.awaitReason === "detached") into.sawDetach = true;
|
|
6305
5817
|
}
|
|
6306
5818
|
}
|
|
6307
5819
|
function withDetachedReconnect(response, reattach, options = {}) {
|
|
@@ -8508,6 +8020,13 @@ function buildEmptySessionNudge(consecutiveEmptySessions) {
|
|
|
8508
8020
|
}
|
|
8509
8021
|
|
|
8510
8022
|
// src/endpoints.ts
|
|
8023
|
+
function buildExecutionEventsPath(executionId, query = {}) {
|
|
8024
|
+
const params = new URLSearchParams();
|
|
8025
|
+
if (query.after) params.set("after", query.after);
|
|
8026
|
+
if (query.conversationId) params.set("conversationId", query.conversationId);
|
|
8027
|
+
const search = params.toString();
|
|
8028
|
+
return `/executions/${encodeURIComponent(executionId)}/events${search ? `?${search}` : ""}`;
|
|
8029
|
+
}
|
|
8511
8030
|
var FlowsEndpoint = class {
|
|
8512
8031
|
constructor(client) {
|
|
8513
8032
|
this.client = client;
|
|
@@ -9191,10 +8710,15 @@ var DispatchEndpoint = class {
|
|
|
9191
8710
|
}
|
|
9192
8711
|
/**
|
|
9193
8712
|
* Dispatch with streaming response
|
|
8713
|
+
*
|
|
8714
|
+
* A dispatched agent turn runs on the durable lane, so its socket can close
|
|
8715
|
+
* with `await` / `awaitReason: 'detached'` while the run continues. The
|
|
8716
|
+
* stream follows that detach through the execution-scoped events alias;
|
|
8717
|
+
* `autoReconnect: false` hands back the raw stream instead.
|
|
9194
8718
|
*/
|
|
9195
|
-
async executeStream(data) {
|
|
8719
|
+
async executeStream(data, init) {
|
|
9196
8720
|
const normalized = normalizeDispatchRequest(data);
|
|
9197
|
-
|
|
8721
|
+
const response = await this.client.requestStream("/dispatch", {
|
|
9198
8722
|
method: "POST",
|
|
9199
8723
|
body: JSON.stringify({
|
|
9200
8724
|
...normalized,
|
|
@@ -9202,8 +8726,32 @@ var DispatchEndpoint = class {
|
|
|
9202
8726
|
...normalized.options,
|
|
9203
8727
|
streamResponse: true
|
|
9204
8728
|
}
|
|
9205
|
-
})
|
|
8729
|
+
}),
|
|
8730
|
+
...init?.signal ? { signal: init.signal } : {}
|
|
9206
8731
|
});
|
|
8732
|
+
return withDetachedReconnect(
|
|
8733
|
+
response,
|
|
8734
|
+
this.buildDetachedReattach(normalized, init?.signal),
|
|
8735
|
+
init ?? {}
|
|
8736
|
+
);
|
|
8737
|
+
}
|
|
8738
|
+
/**
|
|
8739
|
+
* The `?after=` reattach leg a detached dispatch stream is followed with.
|
|
8740
|
+
*
|
|
8741
|
+
* Unlike an agent execute, a dispatch knows no agent id at the call site, so
|
|
8742
|
+
* it rejoins by execution id alone through the execution-scoped alias. The
|
|
8743
|
+
* cursor is the last SSE `id:` the stream delivered, forwarded verbatim.
|
|
8744
|
+
*/
|
|
8745
|
+
buildDetachedReattach(data, signal) {
|
|
8746
|
+
return async ({ executionId, after, signal: reattachSignal }) => {
|
|
8747
|
+
const named = data?.conversationId;
|
|
8748
|
+
const conversationId = typeof named === "string" && named ? named : void 0;
|
|
8749
|
+
const legSignal = combineAbortSignals(signal, reattachSignal);
|
|
8750
|
+
return this.client.requestStream(buildExecutionEventsPath(executionId, { after, conversationId }), {
|
|
8751
|
+
method: "GET",
|
|
8752
|
+
...legSignal ? { signal: legSignal } : {}
|
|
8753
|
+
}).catch(() => null);
|
|
8754
|
+
};
|
|
9207
8755
|
}
|
|
9208
8756
|
/**
|
|
9209
8757
|
* Resume paused flow execution
|
|
@@ -9337,6 +8885,14 @@ var AnalyticsEndpoint = class {
|
|
|
9337
8885
|
async getEndUserUsage(params) {
|
|
9338
8886
|
return this.client.get("/analytics/end-user-usage", params);
|
|
9339
8887
|
}
|
|
8888
|
+
/**
|
|
8889
|
+
* Get reliability, latency, unit economics, and eval health for the current
|
|
8890
|
+
* period against the preceding period of equal length, plus a derived feed of
|
|
8891
|
+
* notable changes.
|
|
8892
|
+
*/
|
|
8893
|
+
async getProductionHealth(params) {
|
|
8894
|
+
return this.client.get("/analytics/production-health", params);
|
|
8895
|
+
}
|
|
9340
8896
|
};
|
|
9341
8897
|
var FlowStepsEndpoint = class {
|
|
9342
8898
|
constructor(client) {
|
|
@@ -9547,7 +9103,7 @@ var ToolsEndpoint = class {
|
|
|
9547
9103
|
return this.client.get(`/tools/builtin/${toolId}/schema`);
|
|
9548
9104
|
}
|
|
9549
9105
|
/**
|
|
9550
|
-
* Deploy
|
|
9106
|
+
* Deploy a Daytona preview; retention defaults to ten minutes and the URL is not durable hosting.
|
|
9551
9107
|
*/
|
|
9552
9108
|
async deploySandbox(data) {
|
|
9553
9109
|
return this.client.post("/tools/sandbox/deploy", data);
|
|
@@ -9559,7 +9115,7 @@ var ToolsEndpoint = class {
|
|
|
9559
9115
|
return this.client.delete(`/tools/sandbox/${sandboxId}`);
|
|
9560
9116
|
}
|
|
9561
9117
|
/**
|
|
9562
|
-
* Deploy
|
|
9118
|
+
* Deploy a Runtype Sandbox preview; omitted retention preserves the legacy unlimited backstop.
|
|
9563
9119
|
*/
|
|
9564
9120
|
async deployCfSandbox(data) {
|
|
9565
9121
|
return this.client.post("/tools/sandbox/cf-sandbox/deploy", data);
|
|
@@ -10018,14 +9574,15 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
10018
9574
|
* conversation-key behavior.
|
|
10019
9575
|
*/
|
|
10020
9576
|
buildDetachedReattach(id, data, signal) {
|
|
10021
|
-
return async ({ executionId, after }) => {
|
|
9577
|
+
return async ({ executionId, after, signal: reattachSignal }) => {
|
|
10022
9578
|
const named = data?.conversationId;
|
|
10023
9579
|
const conversationId = typeof named === "string" ? named : "";
|
|
10024
9580
|
const query = new URLSearchParams({ after });
|
|
10025
9581
|
if (conversationId) query.set("conversationId", conversationId);
|
|
9582
|
+
const legSignal = combineAbortSignals(signal, reattachSignal);
|
|
10026
9583
|
return this.client.requestStream(`/agents/${id}/executions/${executionId}/events?${query.toString()}`, {
|
|
10027
9584
|
method: "GET",
|
|
10028
|
-
...
|
|
9585
|
+
...legSignal ? { signal: legSignal } : {}
|
|
10029
9586
|
}).catch(() => null);
|
|
10030
9587
|
};
|
|
10031
9588
|
}
|
|
@@ -12955,189 +12512,741 @@ var AgentVersionsEndpoint = class {
|
|
|
12955
12512
|
return this.client.get(`/agent-versions/${agentId}/${versionId}`);
|
|
12956
12513
|
}
|
|
12957
12514
|
/**
|
|
12958
|
-
* Publish a version (promote it to the agent's published version).
|
|
12515
|
+
* Publish a version (promote it to the agent's published version).
|
|
12516
|
+
*/
|
|
12517
|
+
async publish(agentId, versionId, options = {}) {
|
|
12518
|
+
return this.client.post(`/agent-versions/${agentId}/publish`, {
|
|
12519
|
+
versionId,
|
|
12520
|
+
...options
|
|
12521
|
+
});
|
|
12522
|
+
}
|
|
12523
|
+
};
|
|
12524
|
+
var FlowVersionsEndpoint = class {
|
|
12525
|
+
constructor(client) {
|
|
12526
|
+
this.client = client;
|
|
12527
|
+
}
|
|
12528
|
+
/**
|
|
12529
|
+
* List versions for a flow, optionally filtered by version `type`.
|
|
12530
|
+
*/
|
|
12531
|
+
async list(flowId, params) {
|
|
12532
|
+
return this.client.get(`/flow-versions/${flowId}`, params);
|
|
12533
|
+
}
|
|
12534
|
+
/**
|
|
12535
|
+
* Get the published version for a flow.
|
|
12536
|
+
*/
|
|
12537
|
+
async getPublished(flowId) {
|
|
12538
|
+
return this.client.get(`/flow-versions/${flowId}/published`);
|
|
12539
|
+
}
|
|
12540
|
+
/**
|
|
12541
|
+
* Get a specific version of a flow.
|
|
12542
|
+
*/
|
|
12543
|
+
async get(flowId, versionId) {
|
|
12544
|
+
return this.client.get(`/flow-versions/${flowId}/${versionId}`);
|
|
12545
|
+
}
|
|
12546
|
+
/**
|
|
12547
|
+
* Publish a version (promote it to the flow's published version).
|
|
12548
|
+
*/
|
|
12549
|
+
async publish(flowId, versionId, options = {}) {
|
|
12550
|
+
return this.client.post(`/flow-versions/${flowId}/publish`, {
|
|
12551
|
+
versionId,
|
|
12552
|
+
...options
|
|
12553
|
+
});
|
|
12554
|
+
}
|
|
12555
|
+
};
|
|
12556
|
+
var IntegrationsEndpoint = class {
|
|
12557
|
+
constructor(client) {
|
|
12558
|
+
this.client = client;
|
|
12559
|
+
}
|
|
12560
|
+
/**
|
|
12561
|
+
* List all integrations with the caller's per-integration configuration status.
|
|
12562
|
+
*/
|
|
12563
|
+
async list(params) {
|
|
12564
|
+
return this.client.get("/integrations", params);
|
|
12565
|
+
}
|
|
12566
|
+
/**
|
|
12567
|
+
* Get a single integration by ID.
|
|
12568
|
+
*/
|
|
12569
|
+
async get(integrationId) {
|
|
12570
|
+
return this.client.get(`/integrations/${integrationId}`);
|
|
12571
|
+
}
|
|
12572
|
+
/**
|
|
12573
|
+
* List integrations within a category (e.g. `slack`, `mcp`).
|
|
12574
|
+
*/
|
|
12575
|
+
async listByCategory(category) {
|
|
12576
|
+
return this.client.get(
|
|
12577
|
+
`/integrations/category/${category}`
|
|
12578
|
+
);
|
|
12579
|
+
}
|
|
12580
|
+
/**
|
|
12581
|
+
* Per-environment credential status across the caller's integrations.
|
|
12582
|
+
*/
|
|
12583
|
+
async getCredentialsStatus() {
|
|
12584
|
+
return this.client.get("/integrations/credentials-status");
|
|
12585
|
+
}
|
|
12586
|
+
/**
|
|
12587
|
+
* List all tools exposed across the caller's configured integrations.
|
|
12588
|
+
*/
|
|
12589
|
+
async listTools() {
|
|
12590
|
+
return this.client.get("/integrations/tools");
|
|
12591
|
+
}
|
|
12592
|
+
/**
|
|
12593
|
+
* List the tools exposed by a single integration.
|
|
12594
|
+
*/
|
|
12595
|
+
async getIntegrationTools(integrationId) {
|
|
12596
|
+
return this.client.get(
|
|
12597
|
+
`/integrations/${integrationId}/tools`
|
|
12598
|
+
);
|
|
12599
|
+
}
|
|
12600
|
+
/**
|
|
12601
|
+
* Get the definition of a single tool within an integration.
|
|
12602
|
+
*/
|
|
12603
|
+
async getTool(integrationId, toolName) {
|
|
12604
|
+
return this.client.get(`/integrations/${integrationId}/tools/${toolName}`);
|
|
12605
|
+
}
|
|
12606
|
+
/**
|
|
12607
|
+
* Install a Slack integration from a completed OAuth handshake.
|
|
12608
|
+
*/
|
|
12609
|
+
async installSlack(data) {
|
|
12610
|
+
return this.client.post("/integrations/slack/install", data);
|
|
12611
|
+
}
|
|
12612
|
+
/**
|
|
12613
|
+
* Start the Slack "Add to Slack" OAuth handshake. Returns the Slack authorize
|
|
12614
|
+
* URL to open in a popup; the bot token is captured server-side by the
|
|
12615
|
+
* callback (never returned to the browser).
|
|
12616
|
+
*/
|
|
12617
|
+
async startSlackOAuth(data) {
|
|
12618
|
+
return this.client.post("/oauth/slack/start", data);
|
|
12619
|
+
}
|
|
12620
|
+
/**
|
|
12621
|
+
* Generate the Slack app manifest for a surface, plus a link to Slack's
|
|
12622
|
+
* app-creation page. The manifest carries absolute API URLs derived
|
|
12623
|
+
* server-side, so it is always valid for Slack (relative proxy paths never
|
|
12624
|
+
* leak in). Slack's create-app modal ignores a manifest passed in the URL, so
|
|
12625
|
+
* `manifestJson` is pasted into its "From a manifest" option rather than
|
|
12626
|
+
* embedded in `createAppUrl`.
|
|
12627
|
+
*/
|
|
12628
|
+
async generateSlackManifest(data) {
|
|
12629
|
+
return this.client.post("/integrations/slack/manifest", data);
|
|
12630
|
+
}
|
|
12631
|
+
/**
|
|
12632
|
+
* Report whether Slack has verified a surface's events URL. Slack sends that
|
|
12633
|
+
* challenge when an app is created from a manifest, so a `verifiedAt` newer
|
|
12634
|
+
* than the one read before the manifest was handed out is evidence the app
|
|
12635
|
+
* now exists. Markers expire after an hour.
|
|
12636
|
+
*/
|
|
12637
|
+
async getSlackAppStatus(surfaceId) {
|
|
12638
|
+
return this.client.get(
|
|
12639
|
+
`/integrations/slack/app-status?surfaceId=${encodeURIComponent(surfaceId)}`
|
|
12640
|
+
);
|
|
12641
|
+
}
|
|
12642
|
+
};
|
|
12643
|
+
var BillingEndpoint = class {
|
|
12644
|
+
constructor(client) {
|
|
12645
|
+
this.client = client;
|
|
12646
|
+
}
|
|
12647
|
+
/**
|
|
12648
|
+
* Get the caller's subscription status, plan limits, and current usage.
|
|
12649
|
+
*/
|
|
12650
|
+
async getStatus() {
|
|
12651
|
+
return this.client.get("/billing/status");
|
|
12652
|
+
}
|
|
12653
|
+
/**
|
|
12654
|
+
* Get the caller's credit grants and available/used totals.
|
|
12655
|
+
*/
|
|
12656
|
+
async getCredits() {
|
|
12657
|
+
return this.client.get("/billing/credits");
|
|
12658
|
+
}
|
|
12659
|
+
/**
|
|
12660
|
+
* Get the caller's exact current UTC-month platform spend from the local
|
|
12661
|
+
* meter used for spend-cap enforcement. Returns 503 when that meter is unavailable.
|
|
12662
|
+
*/
|
|
12663
|
+
async getCurrentSpend() {
|
|
12664
|
+
return this.client.get("/billing/current-spend");
|
|
12665
|
+
}
|
|
12666
|
+
/**
|
|
12667
|
+
* Get spend analytics. The window is controlled by either `period` or `days`
|
|
12668
|
+
* (1–365, defaults to 30).
|
|
12669
|
+
*/
|
|
12670
|
+
async getSpendAnalytics(params) {
|
|
12671
|
+
return this.client.get("/billing/spend-analytics", params);
|
|
12672
|
+
}
|
|
12673
|
+
};
|
|
12674
|
+
var ToolApprovalGrantsEndpoint = class {
|
|
12675
|
+
constructor(client) {
|
|
12676
|
+
this.client = client;
|
|
12677
|
+
}
|
|
12678
|
+
/**
|
|
12679
|
+
* List active remembered tool-approval grants for the authenticated owner,
|
|
12680
|
+
* optionally filtered to a single agent.
|
|
12681
|
+
*/
|
|
12682
|
+
async list(agentId) {
|
|
12683
|
+
const query = agentId ? `?agentId=${encodeURIComponent(agentId)}` : "";
|
|
12684
|
+
const response = await this.client.get(
|
|
12685
|
+
`/tool-approval-grants${query}`
|
|
12686
|
+
);
|
|
12687
|
+
return response.data;
|
|
12688
|
+
}
|
|
12689
|
+
/**
|
|
12690
|
+
* Revoke (soft-delete) a remembered grant so the tool prompts for approval
|
|
12691
|
+
* again on future dispatches.
|
|
12692
|
+
*/
|
|
12693
|
+
async revoke(id) {
|
|
12694
|
+
return this.client.delete(`/tool-approval-grants/${id}`);
|
|
12695
|
+
}
|
|
12696
|
+
};
|
|
12697
|
+
|
|
12698
|
+
// src/runtype.ts
|
|
12699
|
+
var globalConfig = {};
|
|
12700
|
+
var globalClient = null;
|
|
12701
|
+
var RuntypeClient = class {
|
|
12702
|
+
constructor(config = {}) {
|
|
12703
|
+
const baseUrl = config.baseUrl || "https://api.runtype.com";
|
|
12704
|
+
this.apiVersion = config.apiVersion || "v1";
|
|
12705
|
+
this.baseUrl = this.apiVersion ? `${baseUrl}/${this.apiVersion}` : baseUrl;
|
|
12706
|
+
this.timeout = config.timeout || 3e4;
|
|
12707
|
+
this.headers = {
|
|
12708
|
+
"Content-Type": "application/json",
|
|
12709
|
+
...config.headers || {}
|
|
12710
|
+
};
|
|
12711
|
+
if (config.apiKey) {
|
|
12712
|
+
this.headers.Authorization = `Bearer ${config.apiKey}`;
|
|
12713
|
+
}
|
|
12714
|
+
}
|
|
12715
|
+
/**
|
|
12716
|
+
* Set the API key for authentication
|
|
12717
|
+
*/
|
|
12718
|
+
setApiKey(apiKey) {
|
|
12719
|
+
this.headers.Authorization = `Bearer ${apiKey}`;
|
|
12720
|
+
}
|
|
12721
|
+
/**
|
|
12722
|
+
* Generic GET request
|
|
12723
|
+
*/
|
|
12724
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts typed list-param interfaces (no index signature); `unknown` would reject them
|
|
12725
|
+
async get(path, params) {
|
|
12726
|
+
const url = this.buildUrl(path, params);
|
|
12727
|
+
const response = await this.makeRequest(url, {
|
|
12728
|
+
method: "GET",
|
|
12729
|
+
headers: this.headers
|
|
12730
|
+
});
|
|
12731
|
+
return response;
|
|
12732
|
+
}
|
|
12733
|
+
/**
|
|
12734
|
+
* Generic POST request
|
|
12735
|
+
*/
|
|
12736
|
+
async post(path, data, extraHeaders) {
|
|
12737
|
+
const url = this.buildUrl(path);
|
|
12738
|
+
const response = await this.makeRequest(url, {
|
|
12739
|
+
method: "POST",
|
|
12740
|
+
headers: { ...this.headers, ...extraHeaders },
|
|
12741
|
+
body: data ? JSON.stringify(data) : void 0
|
|
12742
|
+
});
|
|
12743
|
+
return response;
|
|
12744
|
+
}
|
|
12745
|
+
/**
|
|
12746
|
+
* Generic PUT request
|
|
12747
|
+
*/
|
|
12748
|
+
async put(path, data) {
|
|
12749
|
+
const url = this.buildUrl(path);
|
|
12750
|
+
const response = await this.makeRequest(url, {
|
|
12751
|
+
method: "PUT",
|
|
12752
|
+
headers: this.headers,
|
|
12753
|
+
body: data ? JSON.stringify(data) : void 0
|
|
12754
|
+
});
|
|
12755
|
+
return response;
|
|
12756
|
+
}
|
|
12757
|
+
/**
|
|
12758
|
+
* Generic PATCH request
|
|
12959
12759
|
*/
|
|
12960
|
-
async
|
|
12961
|
-
|
|
12962
|
-
|
|
12963
|
-
|
|
12760
|
+
async patch(path, data) {
|
|
12761
|
+
const url = this.buildUrl(path);
|
|
12762
|
+
const response = await this.makeRequest(url, {
|
|
12763
|
+
method: "PATCH",
|
|
12764
|
+
headers: this.headers,
|
|
12765
|
+
body: data ? JSON.stringify(data) : void 0
|
|
12964
12766
|
});
|
|
12965
|
-
|
|
12966
|
-
};
|
|
12967
|
-
var FlowVersionsEndpoint = class {
|
|
12968
|
-
constructor(client) {
|
|
12969
|
-
this.client = client;
|
|
12767
|
+
return response;
|
|
12970
12768
|
}
|
|
12971
12769
|
/**
|
|
12972
|
-
*
|
|
12770
|
+
* Generic DELETE request
|
|
12973
12771
|
*/
|
|
12974
|
-
async
|
|
12975
|
-
|
|
12772
|
+
async delete(path) {
|
|
12773
|
+
const url = this.buildUrl(path);
|
|
12774
|
+
const response = await this.makeRequest(url, {
|
|
12775
|
+
method: "DELETE",
|
|
12776
|
+
headers: this.headers
|
|
12777
|
+
});
|
|
12778
|
+
return response;
|
|
12976
12779
|
}
|
|
12977
12780
|
/**
|
|
12978
|
-
*
|
|
12781
|
+
* Generic request that returns raw Response for streaming
|
|
12979
12782
|
*/
|
|
12980
|
-
async
|
|
12981
|
-
|
|
12783
|
+
async requestStream(path, options = {}) {
|
|
12784
|
+
const url = this.buildUrl(path);
|
|
12785
|
+
const headers = {
|
|
12786
|
+
...this.headers,
|
|
12787
|
+
...options.headers
|
|
12788
|
+
};
|
|
12789
|
+
return this.makeRawRequest(url, {
|
|
12790
|
+
...options,
|
|
12791
|
+
headers
|
|
12792
|
+
});
|
|
12982
12793
|
}
|
|
12983
12794
|
/**
|
|
12984
|
-
*
|
|
12795
|
+
* Dispatch flow execution (streaming).
|
|
12796
|
+
*
|
|
12797
|
+
* This is the sole streaming-dispatch chokepoint for the flow builders
|
|
12798
|
+
* (`RuntypeFlowBuilder`), so it normalizes the request to the canonical
|
|
12799
|
+
* `/v1/dispatch` wire contract here — every builder path inherits the same
|
|
12800
|
+
* normalization the `DispatchEndpoint` applies, with no per-builder call.
|
|
12801
|
+
*
|
|
12802
|
+
* A dispatched agent turn runs on the durable lane, so the stream follows a
|
|
12803
|
+
* detach through {@link executionEvents}; pass `autoReconnect: false` to own
|
|
12804
|
+
* the reconnect yourself.
|
|
12985
12805
|
*/
|
|
12986
|
-
async
|
|
12987
|
-
|
|
12806
|
+
async dispatch(config, init) {
|
|
12807
|
+
const normalized = normalizeDispatchRequest(config);
|
|
12808
|
+
const request6 = {
|
|
12809
|
+
...normalized,
|
|
12810
|
+
options: {
|
|
12811
|
+
...normalized.options,
|
|
12812
|
+
streamResponse: true
|
|
12813
|
+
}
|
|
12814
|
+
};
|
|
12815
|
+
const response = await this.requestStream("/dispatch", {
|
|
12816
|
+
method: "POST",
|
|
12817
|
+
body: JSON.stringify(request6),
|
|
12818
|
+
...init?.signal ? { signal: init.signal } : {}
|
|
12819
|
+
});
|
|
12820
|
+
const conversationId = typeof normalized.conversationId === "string" && normalized.conversationId ? normalized.conversationId : void 0;
|
|
12821
|
+
return withDetachedReconnect(
|
|
12822
|
+
response,
|
|
12823
|
+
async ({ executionId, after, signal: reattachSignal }) => {
|
|
12824
|
+
const legSignal = combineAbortSignals(init?.signal, reattachSignal);
|
|
12825
|
+
return this.executionEvents(executionId, {
|
|
12826
|
+
after,
|
|
12827
|
+
...conversationId ? { conversationId } : {},
|
|
12828
|
+
...legSignal ? { signal: legSignal } : {}
|
|
12829
|
+
}).catch(() => null);
|
|
12830
|
+
},
|
|
12831
|
+
init ?? {}
|
|
12832
|
+
);
|
|
12988
12833
|
}
|
|
12989
12834
|
/**
|
|
12990
|
-
*
|
|
12835
|
+
* Dispatch flow execution (non-streaming JSON).
|
|
12836
|
+
*
|
|
12837
|
+
* The non-streaming sibling of {@link dispatch}; it normalizes to the same
|
|
12838
|
+
* canonical wire contract so builders never post a raw, un-normalized body,
|
|
12839
|
+
* and pins `streamResponse: false` so the server returns buffered JSON.
|
|
12991
12840
|
*/
|
|
12992
|
-
async
|
|
12993
|
-
|
|
12994
|
-
|
|
12995
|
-
...
|
|
12841
|
+
async dispatchJson(config) {
|
|
12842
|
+
const normalized = normalizeDispatchRequest(config);
|
|
12843
|
+
return this.post("/dispatch", {
|
|
12844
|
+
...normalized,
|
|
12845
|
+
options: {
|
|
12846
|
+
...normalized.options,
|
|
12847
|
+
streamResponse: false
|
|
12848
|
+
}
|
|
12996
12849
|
});
|
|
12997
12850
|
}
|
|
12998
|
-
|
|
12999
|
-
|
|
13000
|
-
|
|
13001
|
-
this.
|
|
12851
|
+
/** Start a normalized dispatch and return a durable handle immediately. */
|
|
12852
|
+
async dispatchAsync(config) {
|
|
12853
|
+
const normalized = normalizeDispatchRequest(config);
|
|
12854
|
+
return this.post(
|
|
12855
|
+
"/dispatch",
|
|
12856
|
+
{
|
|
12857
|
+
...normalized,
|
|
12858
|
+
options: { ...normalized.options, streamResponse: false }
|
|
12859
|
+
},
|
|
12860
|
+
{ Prefer: "respond-async" }
|
|
12861
|
+
);
|
|
12862
|
+
}
|
|
12863
|
+
async getExecutionStatus(executionId) {
|
|
12864
|
+
return this.get(`/executions/${encodeURIComponent(executionId)}/status`);
|
|
13002
12865
|
}
|
|
13003
12866
|
/**
|
|
13004
|
-
*
|
|
12867
|
+
* Rejoin a durable execution's Server-Sent Events by execution id.
|
|
12868
|
+
*
|
|
12869
|
+
* The execution-scoped alias of the agent events route, so a turn started
|
|
12870
|
+
* through `/v1/dispatch` reconnects without knowing which agent served it.
|
|
12871
|
+
* Pass the last SSE `id:` the stream delivered as `after` to replay strictly
|
|
12872
|
+
* past that cursor and then live-tail while the run is still going. This is
|
|
12873
|
+
* the same leg a detached dispatch stream follows on its own, exposed for a
|
|
12874
|
+
* caller that stores the cursor and reattaches later or from elsewhere.
|
|
12875
|
+
*
|
|
12876
|
+
* @example
|
|
12877
|
+
* ```typescript
|
|
12878
|
+
* const events = await client.executionEvents('aex_123', { after: '118' })
|
|
12879
|
+
* ```
|
|
13005
12880
|
*/
|
|
13006
|
-
async
|
|
13007
|
-
|
|
12881
|
+
async executionEvents(executionId, opts = {}) {
|
|
12882
|
+
const path = buildExecutionEventsPath(executionId, {
|
|
12883
|
+
...opts.after !== void 0 ? { after: opts.after } : {},
|
|
12884
|
+
...opts.conversationId !== void 0 ? { conversationId: opts.conversationId } : {}
|
|
12885
|
+
});
|
|
12886
|
+
return this.requestStream(path, {
|
|
12887
|
+
method: "GET",
|
|
12888
|
+
...opts.signal ? { signal: opts.signal } : {}
|
|
12889
|
+
});
|
|
13008
12890
|
}
|
|
13009
12891
|
/**
|
|
13010
|
-
*
|
|
12892
|
+
* Build full URL with query parameters
|
|
13011
12893
|
*/
|
|
13012
|
-
|
|
13013
|
-
|
|
12894
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- mirrors get()'s permissive params type
|
|
12895
|
+
buildUrl(path, params) {
|
|
12896
|
+
const base = this.baseUrl.endsWith("/") ? this.baseUrl : `${this.baseUrl}/`;
|
|
12897
|
+
const relPath = path.startsWith("/") ? path.slice(1) : path;
|
|
12898
|
+
const url = new URL(relPath, base);
|
|
12899
|
+
if (params) {
|
|
12900
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
12901
|
+
if (value !== void 0 && value !== null) {
|
|
12902
|
+
url.searchParams.set(key, String(value));
|
|
12903
|
+
}
|
|
12904
|
+
});
|
|
12905
|
+
}
|
|
12906
|
+
return url.toString();
|
|
13014
12907
|
}
|
|
13015
12908
|
/**
|
|
13016
|
-
*
|
|
12909
|
+
* Make HTTP request with timeout and error handling
|
|
13017
12910
|
*/
|
|
13018
|
-
async
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
12911
|
+
async makeRequest(url, options) {
|
|
12912
|
+
const response = await this.makeRawRequest(url, options);
|
|
12913
|
+
if (response.status === 204) {
|
|
12914
|
+
return null;
|
|
12915
|
+
}
|
|
12916
|
+
const contentType = response.headers.get("content-type");
|
|
12917
|
+
if (contentType?.includes("application/json")) {
|
|
12918
|
+
return response.json();
|
|
12919
|
+
}
|
|
12920
|
+
return response.text();
|
|
13022
12921
|
}
|
|
13023
12922
|
/**
|
|
13024
|
-
*
|
|
12923
|
+
* Make HTTP request that returns raw Response (for streaming)
|
|
13025
12924
|
*/
|
|
13026
|
-
async
|
|
13027
|
-
|
|
12925
|
+
async makeRawRequest(url, options) {
|
|
12926
|
+
const callerSignal = options.signal ?? void 0;
|
|
12927
|
+
const controller = new AbortController();
|
|
12928
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
12929
|
+
const signal = combineAbortSignals(callerSignal, controller.signal) ?? controller.signal;
|
|
12930
|
+
try {
|
|
12931
|
+
const response = await fetch(url, {
|
|
12932
|
+
...options,
|
|
12933
|
+
signal
|
|
12934
|
+
});
|
|
12935
|
+
clearTimeout(timeoutId);
|
|
12936
|
+
if (!response.ok) {
|
|
12937
|
+
const errorText = await response.text();
|
|
12938
|
+
throw new Error(
|
|
12939
|
+
`API request failed: ${response.status} ${response.statusText} - ${errorText}`
|
|
12940
|
+
);
|
|
12941
|
+
}
|
|
12942
|
+
return response;
|
|
12943
|
+
} catch (error) {
|
|
12944
|
+
clearTimeout(timeoutId);
|
|
12945
|
+
if (error instanceof Error && error.name === "AbortError" && !callerSignal?.aborted) {
|
|
12946
|
+
throw new Error(`Request timeout after ${this.timeout}ms`, { cause: error });
|
|
12947
|
+
}
|
|
12948
|
+
throw error;
|
|
12949
|
+
}
|
|
13028
12950
|
}
|
|
12951
|
+
};
|
|
12952
|
+
var Runtype = class {
|
|
13029
12953
|
/**
|
|
13030
|
-
*
|
|
12954
|
+
* Configure the global Runtype client
|
|
12955
|
+
*
|
|
12956
|
+
* Call this once at app startup to set the API key and other options.
|
|
12957
|
+
* All subsequent calls to Runtype.flows, Runtype.batches, etc. will use this config.
|
|
12958
|
+
*
|
|
12959
|
+
* @example
|
|
12960
|
+
* ```typescript
|
|
12961
|
+
* Runtype.configure({ apiKey: process.env.RUNTYPE_API_KEY })
|
|
12962
|
+
* ```
|
|
13031
12963
|
*/
|
|
13032
|
-
|
|
13033
|
-
|
|
12964
|
+
static configure(config) {
|
|
12965
|
+
globalConfig = { ...globalConfig, ...config };
|
|
12966
|
+
globalClient = new RuntypeClient(globalConfig);
|
|
13034
12967
|
}
|
|
13035
12968
|
/**
|
|
13036
|
-
*
|
|
12969
|
+
* Get the global client instance, creating one if needed
|
|
13037
12970
|
*/
|
|
13038
|
-
|
|
13039
|
-
|
|
13040
|
-
|
|
13041
|
-
|
|
12971
|
+
static getClient() {
|
|
12972
|
+
if (!globalClient) {
|
|
12973
|
+
globalClient = new RuntypeClient(globalConfig);
|
|
12974
|
+
}
|
|
12975
|
+
return globalClient;
|
|
13042
12976
|
}
|
|
13043
12977
|
/**
|
|
13044
|
-
*
|
|
12978
|
+
* Create a new client instance with custom configuration
|
|
12979
|
+
*
|
|
12980
|
+
* Use this when you need a client with different settings than the global one.
|
|
12981
|
+
*
|
|
12982
|
+
* @example
|
|
12983
|
+
* ```typescript
|
|
12984
|
+
* const client = Runtype.createClient({ apiKey: 'different_key' })
|
|
12985
|
+
* ```
|
|
13045
12986
|
*/
|
|
13046
|
-
|
|
13047
|
-
return
|
|
12987
|
+
static createClient(config) {
|
|
12988
|
+
return new RuntypeClient({ ...globalConfig, ...config });
|
|
13048
12989
|
}
|
|
13049
12990
|
/**
|
|
13050
|
-
*
|
|
12991
|
+
* Flows namespace - Build and execute flows
|
|
12992
|
+
*
|
|
12993
|
+
* @example
|
|
12994
|
+
* ```typescript
|
|
12995
|
+
* // Upsert a flow (create or update)
|
|
12996
|
+
* const result = await Runtype.flows.upsert({ name: 'My Flow' })
|
|
12997
|
+
* .prompt({ name: 'Analyze', model: 'gpt-4o', userPrompt: '...' })
|
|
12998
|
+
* .stream()
|
|
12999
|
+
*
|
|
13000
|
+
* // Use an existing flow
|
|
13001
|
+
* const result = await Runtype.flows.use('flow_123')
|
|
13002
|
+
* .withRecord({ name: 'Test' })
|
|
13003
|
+
* .result()
|
|
13004
|
+
*
|
|
13005
|
+
* // Virtual flow (one-off, not saved)
|
|
13006
|
+
* const result = await Runtype.flows.virtual({ name: 'Temp Flow' })
|
|
13007
|
+
* .prompt({ ... })
|
|
13008
|
+
* .stream()
|
|
13009
|
+
* ```
|
|
13051
13010
|
*/
|
|
13052
|
-
|
|
13053
|
-
return this.
|
|
13011
|
+
static get flows() {
|
|
13012
|
+
return new FlowsNamespace(() => this.getClient());
|
|
13054
13013
|
}
|
|
13055
13014
|
/**
|
|
13056
|
-
*
|
|
13057
|
-
*
|
|
13058
|
-
*
|
|
13015
|
+
* Batches namespace - Schedule and manage batch operations
|
|
13016
|
+
*
|
|
13017
|
+
* @example
|
|
13018
|
+
* ```typescript
|
|
13019
|
+
* // Schedule a batch
|
|
13020
|
+
* const batch = await Runtype.batches.schedule({
|
|
13021
|
+
* flowId: 'flow_123',
|
|
13022
|
+
* recordType: 'customers',
|
|
13023
|
+
* })
|
|
13024
|
+
*
|
|
13025
|
+
* // Get batch status
|
|
13026
|
+
* const status = await Runtype.batches.get('batch_456')
|
|
13027
|
+
*
|
|
13028
|
+
* // Cancel a batch
|
|
13029
|
+
* await Runtype.batches.cancel('batch_456')
|
|
13030
|
+
*
|
|
13031
|
+
* // List batches
|
|
13032
|
+
* const batches = await Runtype.batches.list({ status: 'running' })
|
|
13033
|
+
* ```
|
|
13059
13034
|
*/
|
|
13060
|
-
|
|
13061
|
-
return this.
|
|
13035
|
+
static get batches() {
|
|
13036
|
+
return new BatchesNamespace(() => this.getClient());
|
|
13062
13037
|
}
|
|
13063
13038
|
/**
|
|
13064
|
-
*
|
|
13065
|
-
*
|
|
13066
|
-
*
|
|
13067
|
-
*
|
|
13068
|
-
*
|
|
13069
|
-
*
|
|
13039
|
+
* Evals namespace - Run evaluations and compare models
|
|
13040
|
+
*
|
|
13041
|
+
* @example
|
|
13042
|
+
* ```typescript
|
|
13043
|
+
* // Run an eval with streaming
|
|
13044
|
+
* const stream = await Runtype.evals.run({
|
|
13045
|
+
* flowId: 'flow_123',
|
|
13046
|
+
* recordType: 'test_data',
|
|
13047
|
+
* models: [{ stepName: 'Analyze', model: 'gpt-4o' }]
|
|
13048
|
+
* }).stream()
|
|
13049
|
+
*
|
|
13050
|
+
* // Submit eval as batch job
|
|
13051
|
+
* const eval = await Runtype.evals.run({
|
|
13052
|
+
* flowId: 'flow_123',
|
|
13053
|
+
* recordType: 'test_data',
|
|
13054
|
+
* models: [
|
|
13055
|
+
* [{ stepName: 'Analyze', model: 'gpt-5.4' }],
|
|
13056
|
+
* [{ stepName: 'Analyze', model: 'claude-opus-4-6' }],
|
|
13057
|
+
* ]
|
|
13058
|
+
* }).submit()
|
|
13059
|
+
* ```
|
|
13070
13060
|
*/
|
|
13071
|
-
|
|
13072
|
-
return this.
|
|
13061
|
+
static get evals() {
|
|
13062
|
+
return new EvalsNamespace(() => this.getClient());
|
|
13073
13063
|
}
|
|
13074
13064
|
/**
|
|
13075
|
-
*
|
|
13076
|
-
*
|
|
13077
|
-
*
|
|
13078
|
-
*
|
|
13065
|
+
* Prompts namespace - Manage and execute prompts
|
|
13066
|
+
*
|
|
13067
|
+
* @example
|
|
13068
|
+
* ```typescript
|
|
13069
|
+
* // Execute a prompt with streaming
|
|
13070
|
+
* const stream = await Runtype.prompts.run('prompt_123', {
|
|
13071
|
+
* recordId: 'rec_456'
|
|
13072
|
+
* }).stream()
|
|
13073
|
+
*
|
|
13074
|
+
* // Get complete result
|
|
13075
|
+
* const result = await Runtype.prompts.run('prompt_123', {
|
|
13076
|
+
* recordId: 'rec_456'
|
|
13077
|
+
* }).result()
|
|
13078
|
+
*
|
|
13079
|
+
* // CRUD operations
|
|
13080
|
+
* const prompts = await Runtype.prompts.list()
|
|
13081
|
+
* const prompt = await Runtype.prompts.get('prompt_123')
|
|
13082
|
+
* const newPrompt = await Runtype.prompts.create({ ... })
|
|
13083
|
+
* await Runtype.prompts.update('prompt_123', { ... })
|
|
13084
|
+
* await Runtype.prompts.delete('prompt_123')
|
|
13085
|
+
* ```
|
|
13079
13086
|
*/
|
|
13080
|
-
|
|
13081
|
-
return this.
|
|
13082
|
-
`/integrations/slack/app-status?surfaceId=${encodeURIComponent(surfaceId)}`
|
|
13083
|
-
);
|
|
13084
|
-
}
|
|
13085
|
-
};
|
|
13086
|
-
var BillingEndpoint = class {
|
|
13087
|
-
constructor(client) {
|
|
13088
|
-
this.client = client;
|
|
13087
|
+
static get prompts() {
|
|
13088
|
+
return new PromptsNamespace(() => this.getClient());
|
|
13089
13089
|
}
|
|
13090
13090
|
/**
|
|
13091
|
-
*
|
|
13091
|
+
* Skills namespace - Manage Agent Skills (admin/control plane)
|
|
13092
|
+
*
|
|
13093
|
+
* @example
|
|
13094
|
+
* ```typescript
|
|
13095
|
+
* // Create a published skill from a SKILL.md document
|
|
13096
|
+
* const { skill } = await Runtype.skills.create({ markdown: skillMd, publish: true })
|
|
13097
|
+
*
|
|
13098
|
+
* // Bind it to an agent
|
|
13099
|
+
* await Runtype.skills.bind({ agentId: 'agent_123', skillId: skill.id })
|
|
13100
|
+
*
|
|
13101
|
+
* // Review agent-authored proposals
|
|
13102
|
+
* const pending = await Runtype.skills.proposals.list()
|
|
13103
|
+
* await Runtype.skills.proposals.approve(pending[0].id)
|
|
13104
|
+
* ```
|
|
13092
13105
|
*/
|
|
13093
|
-
|
|
13094
|
-
return this.
|
|
13106
|
+
static get skills() {
|
|
13107
|
+
return new SkillsNamespace(() => this.getClient());
|
|
13095
13108
|
}
|
|
13096
13109
|
/**
|
|
13097
|
-
*
|
|
13110
|
+
* Agents namespace - Agent config-as-code (define / ensure / pull)
|
|
13111
|
+
*
|
|
13112
|
+
* @example
|
|
13113
|
+
* ```typescript
|
|
13114
|
+
* import { defineAgent, Runtype } from '@runtypelabs/sdk'
|
|
13115
|
+
*
|
|
13116
|
+
* const assistant = defineAgent({
|
|
13117
|
+
* name: 'Pricing Assistant',
|
|
13118
|
+
* model: 'claude-sonnet-4-6',
|
|
13119
|
+
* systemPrompt: renderPrompt(pricingData),
|
|
13120
|
+
* })
|
|
13121
|
+
*
|
|
13122
|
+
* // Converge at deploy time (idempotent; one tiny probe in steady state)
|
|
13123
|
+
* await Runtype.agents.ensure(assistant)
|
|
13124
|
+
*
|
|
13125
|
+
* // CI drift gate
|
|
13126
|
+
* await Runtype.agents.ensure(assistant, { expectNoChanges: true })
|
|
13127
|
+
*
|
|
13128
|
+
* // Absorb a dashboard edit back into the repo
|
|
13129
|
+
* const { definition } = await Runtype.agents.pull('Pricing Assistant')
|
|
13130
|
+
* ```
|
|
13098
13131
|
*/
|
|
13099
|
-
|
|
13100
|
-
return this.
|
|
13132
|
+
static get agents() {
|
|
13133
|
+
return new AgentsNamespace(() => this.getClient());
|
|
13101
13134
|
}
|
|
13102
|
-
/**
|
|
13103
|
-
|
|
13104
|
-
|
|
13105
|
-
*/
|
|
13106
|
-
async getCurrentSpend() {
|
|
13107
|
-
return this.client.get("/billing/current-spend");
|
|
13135
|
+
/** Poll durable handles returned by asynchronous execute operations. */
|
|
13136
|
+
static get executions() {
|
|
13137
|
+
return new ExecutionsNamespace(() => this.getClient());
|
|
13108
13138
|
}
|
|
13109
13139
|
/**
|
|
13110
|
-
*
|
|
13111
|
-
*
|
|
13140
|
+
* Tools namespace - Tool config-as-code (define / ensure / pull)
|
|
13141
|
+
*
|
|
13142
|
+
* @example
|
|
13143
|
+
* ```typescript
|
|
13144
|
+
* import { defineTool, Runtype } from '@runtypelabs/sdk'
|
|
13145
|
+
*
|
|
13146
|
+
* const weather = defineTool({
|
|
13147
|
+
* name: 'Weather Lookup',
|
|
13148
|
+
* description: 'Fetch the current weather for a city',
|
|
13149
|
+
* toolType: 'external',
|
|
13150
|
+
* parametersSchema: { type: 'object', properties: { city: { type: 'string' } } },
|
|
13151
|
+
* config: { url: 'https://api.example.com/weather', method: 'GET' },
|
|
13152
|
+
* })
|
|
13153
|
+
*
|
|
13154
|
+
* // Converge at deploy time (idempotent; one tiny probe in steady state)
|
|
13155
|
+
* await Runtype.tools.ensure(weather)
|
|
13156
|
+
*
|
|
13157
|
+
* // CI drift gate
|
|
13158
|
+
* await Runtype.tools.ensure(weather, { expectNoChanges: true })
|
|
13159
|
+
*
|
|
13160
|
+
* // Absorb a dashboard edit back into the repo
|
|
13161
|
+
* const { definition } = await Runtype.tools.pull('Weather Lookup')
|
|
13162
|
+
* ```
|
|
13112
13163
|
*/
|
|
13113
|
-
|
|
13114
|
-
return this.
|
|
13115
|
-
}
|
|
13116
|
-
};
|
|
13117
|
-
var ToolApprovalGrantsEndpoint = class {
|
|
13118
|
-
constructor(client) {
|
|
13119
|
-
this.client = client;
|
|
13164
|
+
static get tools() {
|
|
13165
|
+
return new ToolsNamespace(() => this.getClient());
|
|
13120
13166
|
}
|
|
13121
13167
|
/**
|
|
13122
|
-
*
|
|
13123
|
-
*
|
|
13168
|
+
* Products namespace - Product config-as-code (define / ensure / pull)
|
|
13169
|
+
*
|
|
13170
|
+
* Converges the top-level product record (description, icon, spec). Nested
|
|
13171
|
+
* capabilities/surfaces/tools and the canvas UI layout state are not
|
|
13172
|
+
* converged by ensure.
|
|
13173
|
+
*
|
|
13174
|
+
* @example
|
|
13175
|
+
* ```typescript
|
|
13176
|
+
* import { defineProduct, Runtype } from '@runtypelabs/sdk'
|
|
13177
|
+
*
|
|
13178
|
+
* const product = defineProduct({
|
|
13179
|
+
* name: 'Support Copilot',
|
|
13180
|
+
* description: 'An AI support assistant',
|
|
13181
|
+
* icon: '🤖',
|
|
13182
|
+
* spec: { productGoal: 'Deflect tier-1 tickets', productStage: 'beta' },
|
|
13183
|
+
* })
|
|
13184
|
+
*
|
|
13185
|
+
* // Converge at deploy time (idempotent; one tiny probe in steady state)
|
|
13186
|
+
* await Runtype.products.ensure(product)
|
|
13187
|
+
*
|
|
13188
|
+
* // CI drift gate
|
|
13189
|
+
* await Runtype.products.ensure(product, { expectNoChanges: true })
|
|
13190
|
+
*
|
|
13191
|
+
* // Absorb a dashboard edit back into the repo
|
|
13192
|
+
* const { definition } = await Runtype.products.pull('Support Copilot')
|
|
13193
|
+
* ```
|
|
13124
13194
|
*/
|
|
13125
|
-
|
|
13126
|
-
|
|
13127
|
-
const response = await this.client.get(
|
|
13128
|
-
`/tool-approval-grants${query}`
|
|
13129
|
-
);
|
|
13130
|
-
return response.data;
|
|
13195
|
+
static get products() {
|
|
13196
|
+
return new ProductsNamespace(() => this.getClient());
|
|
13131
13197
|
}
|
|
13132
13198
|
/**
|
|
13133
|
-
*
|
|
13134
|
-
*
|
|
13199
|
+
* Config-as-code operations for product surfaces. `surfaces.ensure` is the
|
|
13200
|
+
* deploy-time, non-executing converge (create-or-update a surface by name
|
|
13201
|
+
* within a product); `surfaces.pull` is the absorb-drift direction.
|
|
13202
|
+
*
|
|
13203
|
+
* @example
|
|
13204
|
+
* ```typescript
|
|
13205
|
+
* import { Runtype, defineSurface } from '@runtypelabs/sdk'
|
|
13206
|
+
*
|
|
13207
|
+
* const chat = defineSurface({
|
|
13208
|
+
* name: 'Support Chat',
|
|
13209
|
+
* type: 'chat',
|
|
13210
|
+
* behavior: { type: 'chat', greeting: 'Hi there!' },
|
|
13211
|
+
* status: 'active',
|
|
13212
|
+
* })
|
|
13213
|
+
*
|
|
13214
|
+
* // Converge at deploy time (idempotent; one tiny probe in steady state)
|
|
13215
|
+
* await Runtype.surfaces.ensure('product_abc', chat)
|
|
13216
|
+
*
|
|
13217
|
+
* // CI drift gate
|
|
13218
|
+
* await Runtype.surfaces.ensure('product_abc', chat, { expectNoChanges: true })
|
|
13219
|
+
*
|
|
13220
|
+
* // Absorb a dashboard edit back into the repo
|
|
13221
|
+
* const { definition } = await Runtype.surfaces.pull('product_abc', 'Support Chat')
|
|
13222
|
+
* ```
|
|
13135
13223
|
*/
|
|
13136
|
-
|
|
13137
|
-
return this.
|
|
13224
|
+
static get surfaces() {
|
|
13225
|
+
return new SurfacesNamespace(() => this.getClient());
|
|
13138
13226
|
}
|
|
13139
13227
|
};
|
|
13140
13228
|
|
|
13229
|
+
// src/transform.ts
|
|
13230
|
+
function transformQueryParams(params) {
|
|
13231
|
+
const result = {};
|
|
13232
|
+
for (const [key, value] of Object.entries(params)) {
|
|
13233
|
+
if (value !== void 0 && value !== null) {
|
|
13234
|
+
if (Array.isArray(value)) {
|
|
13235
|
+
result[key] = value.join(",");
|
|
13236
|
+
} else {
|
|
13237
|
+
result[key] = String(value);
|
|
13238
|
+
}
|
|
13239
|
+
}
|
|
13240
|
+
}
|
|
13241
|
+
return result;
|
|
13242
|
+
}
|
|
13243
|
+
|
|
13244
|
+
// src/version.ts
|
|
13245
|
+
var FALLBACK_VERSION = "0.0.0";
|
|
13246
|
+
var SDK_VERSION = "9.10.0".length > 0 ? "9.10.0" : FALLBACK_VERSION;
|
|
13247
|
+
var RUNTYPE_CLIENT_KIND = "sdk";
|
|
13248
|
+
var SDK_USER_AGENT = `runtype-sdk/${SDK_VERSION} (typescript)`;
|
|
13249
|
+
|
|
13141
13250
|
// src/client.ts
|
|
13142
13251
|
function isObjectRecord(value) {
|
|
13143
13252
|
return typeof value === "object" && value !== null;
|
|
@@ -14476,12 +14585,14 @@ export {
|
|
|
14476
14585
|
attachRuntimeToolsToDispatchRequest,
|
|
14477
14586
|
buildAgentAdmissionHeaders,
|
|
14478
14587
|
buildEmptySessionNudge,
|
|
14588
|
+
buildExecutionEventsPath,
|
|
14479
14589
|
buildGeneratedRuntimeToolGateOutput,
|
|
14480
14590
|
buildLedgerOffloadReference,
|
|
14481
14591
|
buildObservationMaskMarker,
|
|
14482
14592
|
buildPolicyGuidance,
|
|
14483
14593
|
buildSendViewOffloadMarker,
|
|
14484
14594
|
calledTool,
|
|
14595
|
+
combineAbortSignals,
|
|
14485
14596
|
compileWorkflowConfig,
|
|
14486
14597
|
completed,
|
|
14487
14598
|
computeAgentContentHash,
|