blazen 0.5.3 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blazen.workers.js +10 -0
- package/error-classes.js +111 -0
- package/index.d.ts +344 -7
- package/index.js +73 -0
- package/package.json +8 -8
package/blazen.workers.js
CHANGED
|
@@ -81,6 +81,8 @@ export const AnthropicProvider = __napiModule.exports.AnthropicProvider
|
|
|
81
81
|
export const JsAnthropicProvider = __napiModule.exports.JsAnthropicProvider
|
|
82
82
|
export const ApiProtocol = __napiModule.exports.ApiProtocol
|
|
83
83
|
export const JsApiProtocol = __napiModule.exports.JsApiProtocol
|
|
84
|
+
export const AssignmentContext = __napiModule.exports.AssignmentContext
|
|
85
|
+
export const JsAssignmentContext = __napiModule.exports.JsAssignmentContext
|
|
84
86
|
export const AudioMusicProviderDefaults = __napiModule.exports.AudioMusicProviderDefaults
|
|
85
87
|
export const JsAudioMusicProviderDefaults = __napiModule.exports.JsAudioMusicProviderDefaults
|
|
86
88
|
export const AudioSpeechProviderDefaults = __napiModule.exports.AudioSpeechProviderDefaults
|
|
@@ -137,6 +139,12 @@ export const ContentStore = __napiModule.exports.ContentStore
|
|
|
137
139
|
export const JsContentStore = __napiModule.exports.JsContentStore
|
|
138
140
|
export const Context = __napiModule.exports.Context
|
|
139
141
|
export const JsContext = __napiModule.exports.JsContext
|
|
142
|
+
export const ControlPlaneClient = __napiModule.exports.ControlPlaneClient
|
|
143
|
+
export const JsControlPlaneClient = __napiModule.exports.JsControlPlaneClient
|
|
144
|
+
export const ControlPlaneWorker = __napiModule.exports.ControlPlaneWorker
|
|
145
|
+
export const JsControlPlaneWorker = __napiModule.exports.JsControlPlaneWorker
|
|
146
|
+
export const ControlPlaneWorkerConfig = __napiModule.exports.ControlPlaneWorkerConfig
|
|
147
|
+
export const JsControlPlaneWorkerConfig = __napiModule.exports.JsControlPlaneWorkerConfig
|
|
140
148
|
export const CustomProvider = __napiModule.exports.CustomProvider
|
|
141
149
|
export const JsCustomProvider = __napiModule.exports.JsCustomProvider
|
|
142
150
|
export const DeepSeekProvider = __napiModule.exports.DeepSeekProvider
|
|
@@ -422,6 +430,7 @@ export const initPrometheus = __napiModule.exports.initPrometheus
|
|
|
422
430
|
export const internEventType = __napiModule.exports.internEventType
|
|
423
431
|
export const JoinStrategy = __napiModule.exports.JoinStrategy
|
|
424
432
|
export const JsJoinStrategy = __napiModule.exports.JsJoinStrategy
|
|
433
|
+
export const JsAdmissionModeTag = __napiModule.exports.JsAdmissionModeTag
|
|
425
434
|
export const JsAuthMethod = __napiModule.exports.JsAuthMethod
|
|
426
435
|
export const JsCacheStrategy = __napiModule.exports.JsCacheStrategy
|
|
427
436
|
export const JsContentKind = __napiModule.exports.JsContentKind
|
|
@@ -429,6 +438,7 @@ export const JsDiffusionScheduler = __napiModule.exports.JsDiffusionScheduler
|
|
|
429
438
|
export const JsFalLlmEndpointKind = __napiModule.exports.JsFalLlmEndpointKind
|
|
430
439
|
export const JsJobStatus = __napiModule.exports.JsJobStatus
|
|
431
440
|
export const JsRole = __napiModule.exports.JsRole
|
|
441
|
+
export const JsRunStatus = __napiModule.exports.JsRunStatus
|
|
432
442
|
export const JsWhisperModel = __napiModule.exports.JsWhisperModel
|
|
433
443
|
export const LlamaCppChatRole = __napiModule.exports.LlamaCppChatRole
|
|
434
444
|
export const JsLlamaCppChatRole = __napiModule.exports.JsLlamaCppChatRole
|
package/error-classes.js
CHANGED
|
@@ -23,6 +23,77 @@
|
|
|
23
23
|
|
|
24
24
|
const PROVIDER_ERROR_SENTINEL = '__BLAZEN_PROVIDER_ERROR__'
|
|
25
25
|
|
|
26
|
+
// Sentinel + stash for caller-error preservation. The napi side
|
|
27
|
+
// formats `__BLAZEN_CALLER_ERROR__ {json} \n [CallerError] msg` when a
|
|
28
|
+
// user's tool handler threw. The JSON `ref` is a UUID that maps to an
|
|
29
|
+
// entry in `callerErrorStash` (populated by `wrapToolHandlerForCallerErrors`
|
|
30
|
+
// below); the stashed value is the ORIGINAL JS Error instance -- so
|
|
31
|
+
// `enrichError` can re-throw it verbatim, preserving `instanceof MyError`
|
|
32
|
+
// and all custom properties. See `crates/blazen-node/src/error.rs`
|
|
33
|
+
// CALLER_ERROR_SENTINEL.
|
|
34
|
+
const CALLER_ERROR_SENTINEL = '__BLAZEN_CALLER_ERROR__'
|
|
35
|
+
|
|
36
|
+
// Module-level Map keyed by UUID strings. Values are the original
|
|
37
|
+
// thrown JS Error instances. Each entry is added by
|
|
38
|
+
// `wrapToolHandlerForCallerErrors` and deleted in `enrichError` after
|
|
39
|
+
// re-throw (or fall-back). Entries that escape the stash because the
|
|
40
|
+
// agent loop produced a non-CallerError outcome are cleaned up by the
|
|
41
|
+
// `runAgent` wrapper's `.finally(...)` (see `wrapRunAgentForCallerErrors`
|
|
42
|
+
// in index.js).
|
|
43
|
+
const callerErrorStash = new Map()
|
|
44
|
+
|
|
45
|
+
// Build a fresh UUID string suitable for Map keys. Uses the built-in
|
|
46
|
+
// crypto.randomUUID() when available (Node 14.17+); falls back to a
|
|
47
|
+
// simple time+random pattern otherwise.
|
|
48
|
+
function freshUuid() {
|
|
49
|
+
try {
|
|
50
|
+
// eslint-disable-next-line global-require
|
|
51
|
+
const { randomUUID } = require('crypto')
|
|
52
|
+
if (typeof randomUUID === 'function') {
|
|
53
|
+
return randomUUID()
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
// Fall through.
|
|
57
|
+
}
|
|
58
|
+
return `caller-${Date.now()}-${Math.random().toString(36).slice(2)}`
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Wrap a user-supplied tool handler so any thrown / rejected error is
|
|
62
|
+
// captured as an envelope `{__blazenOk: false, errorRef: uuid, errorName,
|
|
63
|
+
// errorMessage}` and stashed for `enrichError` to re-throw. Success
|
|
64
|
+
// returns become `{__blazenOk: true, value: <user's return>}`.
|
|
65
|
+
//
|
|
66
|
+
// Returns a freshly-wrapped function (does NOT mutate the user's
|
|
67
|
+
// handler). The wrapped function is what the napi `runAgent` /
|
|
68
|
+
// `runAgentWithCallback` Rust side sees.
|
|
69
|
+
//
|
|
70
|
+
// The wrapped function returns a Promise (always) so the napi
|
|
71
|
+
// `Promise<serde_json::Value>` resolution path is uniform regardless of
|
|
72
|
+
// whether the user's handler is sync or async.
|
|
73
|
+
function wrapToolHandlerForCallerErrors(handler) {
|
|
74
|
+
if (typeof handler !== 'function') {
|
|
75
|
+
return handler
|
|
76
|
+
}
|
|
77
|
+
return async function blazenEnvelopeToolHandler(...args) {
|
|
78
|
+
try {
|
|
79
|
+
const value = await handler.apply(this, args)
|
|
80
|
+
return { __blazenOk: true, value }
|
|
81
|
+
} catch (error) {
|
|
82
|
+
const ref = freshUuid()
|
|
83
|
+
callerErrorStash.set(ref, error)
|
|
84
|
+
const errorName =
|
|
85
|
+
(error && typeof error === 'object' && typeof error.name === 'string')
|
|
86
|
+
? error.name
|
|
87
|
+
: undefined
|
|
88
|
+
const errorMessage =
|
|
89
|
+
(error && typeof error === 'object' && typeof error.message === 'string')
|
|
90
|
+
? error.message
|
|
91
|
+
: String(error)
|
|
92
|
+
return { __blazenOk: false, errorRef: ref, errorName, errorMessage }
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
26
97
|
// ---------------------------------------------------------------------------
|
|
27
98
|
// Class hierarchy
|
|
28
99
|
// ---------------------------------------------------------------------------
|
|
@@ -702,6 +773,41 @@ function enrichError(err) {
|
|
|
702
773
|
}
|
|
703
774
|
}
|
|
704
775
|
|
|
776
|
+
// Detect and strip the caller-error sentinel. If the stash has the
|
|
777
|
+
// original error, re-throw it verbatim (preserves `instanceof MyError`
|
|
778
|
+
// and all custom properties). Otherwise fall back to a generic Error
|
|
779
|
+
// carrying the name+message from the sentinel JSON.
|
|
780
|
+
if (message.startsWith(CALLER_ERROR_SENTINEL)) {
|
|
781
|
+
const newlineIdx = message.indexOf('\n')
|
|
782
|
+
let payload = null
|
|
783
|
+
if (newlineIdx !== -1) {
|
|
784
|
+
const jsonPart = message
|
|
785
|
+
.slice(CALLER_ERROR_SENTINEL.length, newlineIdx)
|
|
786
|
+
.trim()
|
|
787
|
+
try {
|
|
788
|
+
payload = JSON.parse(jsonPart)
|
|
789
|
+
} catch {
|
|
790
|
+
payload = null
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
if (payload && typeof payload.ref === 'string') {
|
|
794
|
+
const original = callerErrorStash.get(payload.ref)
|
|
795
|
+
callerErrorStash.delete(payload.ref)
|
|
796
|
+
if (original !== undefined) {
|
|
797
|
+
return original
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
// Fallback: construct a generic Error with the sentinel-embedded
|
|
801
|
+
// name and message. instanceof won't match, but `.name` / `.message`
|
|
802
|
+
// still let consumers branch on the error type.
|
|
803
|
+
const fallback = new Error((payload && payload.message) || 'caller error')
|
|
804
|
+
if (payload && typeof payload.name === 'string') {
|
|
805
|
+
fallback.name = payload.name
|
|
806
|
+
}
|
|
807
|
+
fallback.stack = err.stack
|
|
808
|
+
return fallback
|
|
809
|
+
}
|
|
810
|
+
|
|
705
811
|
const match = TAG_RE.exec(message)
|
|
706
812
|
if (!match) {
|
|
707
813
|
return err
|
|
@@ -852,4 +958,9 @@ module.exports = {
|
|
|
852
958
|
|
|
853
959
|
// Helper
|
|
854
960
|
enrichError,
|
|
961
|
+
|
|
962
|
+
// Caller-error preservation
|
|
963
|
+
CALLER_ERROR_SENTINEL,
|
|
964
|
+
wrapToolHandlerForCallerErrors,
|
|
965
|
+
callerErrorStash,
|
|
855
966
|
}
|
package/index.d.ts
CHANGED
|
@@ -93,6 +93,26 @@ export declare class ApiProtocol {
|
|
|
93
93
|
}
|
|
94
94
|
export type JsApiProtocol = ApiProtocol
|
|
95
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Per-assignment context handed to the JS handler. Mirrors
|
|
98
|
+
* [`blazen_controlplane::AssignmentContext`].
|
|
99
|
+
*
|
|
100
|
+
* Carries the run id and a sink for emitting non-terminal events back
|
|
101
|
+
* to the control plane.
|
|
102
|
+
*/
|
|
103
|
+
export declare class AssignmentContext {
|
|
104
|
+
/** Run identifier this context belongs to (UUID string). */
|
|
105
|
+
get runId(): string
|
|
106
|
+
/**
|
|
107
|
+
* Emit a non-terminal event back to the control plane.
|
|
108
|
+
*
|
|
109
|
+
* `data` must be a JSON-serializable JS value (object, array,
|
|
110
|
+
* string, number, boolean, null).
|
|
111
|
+
*/
|
|
112
|
+
emitEvent(eventType: string, data: any): Promise<void>
|
|
113
|
+
}
|
|
114
|
+
export type JsAssignmentContext = AssignmentContext
|
|
115
|
+
|
|
96
116
|
export declare class AudioMusicProviderDefaults {
|
|
97
117
|
/** Construct role-specific defaults. */
|
|
98
118
|
constructor(base?: BaseProviderDefaults | undefined | null, before?: BeforeRoleTsfn | undefined | null)
|
|
@@ -1439,6 +1459,131 @@ export declare class Context {
|
|
|
1439
1459
|
}
|
|
1440
1460
|
export type JsContext = Context
|
|
1441
1461
|
|
|
1462
|
+
/**
|
|
1463
|
+
* Orchestrator-side client for the control plane. Submit / cancel /
|
|
1464
|
+
* describe runs, list workers, drain workers, subscribe to events.
|
|
1465
|
+
*
|
|
1466
|
+
* ```typescript
|
|
1467
|
+
* const client = await ControlPlaneClient.connect("http://cp:7445");
|
|
1468
|
+
* const snap = await client.submitWorkflow({
|
|
1469
|
+
* workflowName: "summarize",
|
|
1470
|
+
* input: { url: "https://example.com" },
|
|
1471
|
+
* waitForWorker: true,
|
|
1472
|
+
* });
|
|
1473
|
+
* for await (const event of client.subscribeRunEvents(snap.runId)) {
|
|
1474
|
+
* console.log(event.eventType, event.data);
|
|
1475
|
+
* }
|
|
1476
|
+
* ```
|
|
1477
|
+
*/
|
|
1478
|
+
export declare class ControlPlaneClient {
|
|
1479
|
+
/**
|
|
1480
|
+
* Open a connection to the control plane at `endpoint`. Pass
|
|
1481
|
+
* `{ mtls: { cert, key, ca } }` to use mTLS.
|
|
1482
|
+
*/
|
|
1483
|
+
static connect(endpoint: string, opts?: JsClientConnectOptions | undefined | null): Promise<ControlPlaneClient>
|
|
1484
|
+
/** Submit a workflow run. */
|
|
1485
|
+
submitWorkflow(opts: JsSubmitWorkflowOptions): Promise<JsRunStateSnapshot>
|
|
1486
|
+
/** Cancel an in-flight workflow run. */
|
|
1487
|
+
cancelWorkflow(runId: string): Promise<JsRunStateSnapshot>
|
|
1488
|
+
/** Describe the current state of a workflow run. */
|
|
1489
|
+
describeWorkflow(runId: string): Promise<JsRunStateSnapshot>
|
|
1490
|
+
/** List currently-connected workers. */
|
|
1491
|
+
listWorkers(): Promise<Array<JsWorkerInfo>>
|
|
1492
|
+
/**
|
|
1493
|
+
* Drain a worker. Pass `immediate = true` to refuse new work right
|
|
1494
|
+
* away; otherwise let in-flight runs finish first.
|
|
1495
|
+
*/
|
|
1496
|
+
drainWorker(nodeId: string, immediate: boolean): Promise<void>
|
|
1497
|
+
/**
|
|
1498
|
+
* Subscribe to events for a specific run. The returned stream is
|
|
1499
|
+
* a JS `AsyncIterableIterator<RunEvent>` (object with both `next`
|
|
1500
|
+
* and `[Symbol.asyncIterator]`).
|
|
1501
|
+
*/
|
|
1502
|
+
subscribeRunEvents(runId: string): AsyncIterableIterator<RunEvent>
|
|
1503
|
+
/**
|
|
1504
|
+
* Subscribe to events across all runs, optionally filtered by tag
|
|
1505
|
+
* predicates. Returns an `AsyncIterableIterator<RunEvent>`.
|
|
1506
|
+
*/
|
|
1507
|
+
subscribeAll(opts?: JsSubscribeAllOptions | undefined | null): AsyncIterableIterator<RunEvent>
|
|
1508
|
+
}
|
|
1509
|
+
export type JsControlPlaneClient = ControlPlaneClient
|
|
1510
|
+
|
|
1511
|
+
/**
|
|
1512
|
+
* Worker connection to a control-plane server. Construct via
|
|
1513
|
+
* [`Self::connect`] (which validates the endpoint URI), then call
|
|
1514
|
+
* [`Self::run`] with a JS handler to drive the worker forever.
|
|
1515
|
+
*
|
|
1516
|
+
* ```typescript
|
|
1517
|
+
* const config = new ControlPlaneWorkerConfig("http://cp:7445", "node-a")
|
|
1518
|
+
* .withCapability({ kind: "workflow:summarize", version: 1 });
|
|
1519
|
+
* const worker = ControlPlaneWorker.connect(config);
|
|
1520
|
+
* await worker.run(async (assignment, ctx) => {
|
|
1521
|
+
* await ctx.emitEvent("started", { runId: assignment.runId });
|
|
1522
|
+
* return { ok: true };
|
|
1523
|
+
* });
|
|
1524
|
+
* ```
|
|
1525
|
+
*/
|
|
1526
|
+
export declare class ControlPlaneWorker {
|
|
1527
|
+
/**
|
|
1528
|
+
* Validate the configured endpoint URI and prepare a worker that's
|
|
1529
|
+
* ready to call [`Self::run`]. Does NOT open a network connection
|
|
1530
|
+
* yet — that happens on the first iteration of `run`.
|
|
1531
|
+
*/
|
|
1532
|
+
static connect(config: ControlPlaneWorkerConfig): ControlPlaneWorker
|
|
1533
|
+
/**
|
|
1534
|
+
* Drive the worker forever, dispatching each assignment to the JS
|
|
1535
|
+
* handler. Resolves on graceful drain or [`Self::shutdown`].
|
|
1536
|
+
*
|
|
1537
|
+
* The JS handler is invoked with two arguments: the assignment
|
|
1538
|
+
* itself and a [`JsAssignmentContext`] that exposes the run id and
|
|
1539
|
+
* an `emitEvent` method. Its return value (JSON-serialized) becomes
|
|
1540
|
+
* the assignment output reported back to the server.
|
|
1541
|
+
*/
|
|
1542
|
+
run(handler: (assignment: Assignment, ctx: AssignmentContext) => Promise<unknown>): Promise<void>
|
|
1543
|
+
/**
|
|
1544
|
+
* Signal the worker to stop. Idempotent.
|
|
1545
|
+
*
|
|
1546
|
+
* This drops the cancellation token tied to [`Self::run`]; the
|
|
1547
|
+
* `run` future resolves at the next await point.
|
|
1548
|
+
*/
|
|
1549
|
+
shutdown(): void
|
|
1550
|
+
}
|
|
1551
|
+
export type JsControlPlaneWorker = ControlPlaneWorker
|
|
1552
|
+
|
|
1553
|
+
/**
|
|
1554
|
+
* Fluent builder for a worker connection. Mirrors
|
|
1555
|
+
* [`blazen_controlplane::WorkerConfig`].
|
|
1556
|
+
*
|
|
1557
|
+
* ```typescript
|
|
1558
|
+
* const config = new ControlPlaneWorkerConfig("http://cp:7445", "node-a")
|
|
1559
|
+
* .withCapability({ kind: "workflow:summarize", version: 1 })
|
|
1560
|
+
* .withTag("region", "us-west")
|
|
1561
|
+
* .withAdmission({ type: "Fixed", maxInFlight: 4 });
|
|
1562
|
+
* ```
|
|
1563
|
+
*/
|
|
1564
|
+
export declare class ControlPlaneWorkerConfig {
|
|
1565
|
+
/**
|
|
1566
|
+
* Build a config with the required `endpoint` URI and stable
|
|
1567
|
+
* `nodeId`. Defaults: no capabilities, no tags, `Fixed { maxInFlight: 1 }`,
|
|
1568
|
+
* 5s heartbeat, plaintext transport.
|
|
1569
|
+
*/
|
|
1570
|
+
constructor(endpoint: string, nodeId: string)
|
|
1571
|
+
/** Append a capability advertised at handshake. */
|
|
1572
|
+
withCapability(cap: JsWorkerCapability): this
|
|
1573
|
+
/**
|
|
1574
|
+
* Insert a free-form `key=value` tag used by submission-time tag
|
|
1575
|
+
* predicates.
|
|
1576
|
+
*/
|
|
1577
|
+
withTag(key: string, value: string): this
|
|
1578
|
+
/** Override the admission mode declared at handshake. */
|
|
1579
|
+
withAdmission(mode: JsAdmissionMode): this
|
|
1580
|
+
/** Override the heartbeat cadence (milliseconds). */
|
|
1581
|
+
withHeartbeatIntervalMs(ms: number): this
|
|
1582
|
+
/** Load a client identity + CA from PEM files and use them for mTLS. */
|
|
1583
|
+
withMtls(certPath: string, keyPath: string, caPath: string): this
|
|
1584
|
+
}
|
|
1585
|
+
export type JsControlPlaneWorkerConfig = ControlPlaneWorkerConfig
|
|
1586
|
+
|
|
1442
1587
|
/**
|
|
1443
1588
|
* A user-defined Blazen provider exposed to JavaScript.
|
|
1444
1589
|
*
|
|
@@ -6543,6 +6688,35 @@ export interface JsAddEntry {
|
|
|
6543
6688
|
metadata?: any
|
|
6544
6689
|
}
|
|
6545
6690
|
|
|
6691
|
+
/**
|
|
6692
|
+
* JS-facing admission mode. The `type` field discriminates the variant:
|
|
6693
|
+
* `'Fixed'` requires `maxInFlight`, `'VramBudget'` requires `totalMb`,
|
|
6694
|
+
* and `'Reactive'` has no payload fields.
|
|
6695
|
+
*/
|
|
6696
|
+
export interface JsAdmissionMode {
|
|
6697
|
+
/** Discriminator: `'Fixed'`, `'Reactive'`, or `'VramBudget'`. */
|
|
6698
|
+
type: JsAdmissionModeTag
|
|
6699
|
+
/** In-flight cap for `Fixed`. `None` for the other variants. */
|
|
6700
|
+
maxInFlight?: number
|
|
6701
|
+
/**
|
|
6702
|
+
* VRAM budget in megabytes for `VramBudget`. `None` for the other
|
|
6703
|
+
* variants.
|
|
6704
|
+
*/
|
|
6705
|
+
totalMb?: bigint
|
|
6706
|
+
}
|
|
6707
|
+
|
|
6708
|
+
/**
|
|
6709
|
+
* JS-facing label that drives [`JsAdmissionMode::r#type`]. Carries the
|
|
6710
|
+
* same three variants as [`AdmissionMode`] but as a plain string union
|
|
6711
|
+
* rather than a tagged enum (napi-rs `#[napi(object)]` does not yet
|
|
6712
|
+
* support discriminated-union codegen for enums with associated data).
|
|
6713
|
+
*/
|
|
6714
|
+
export declare const enum JsAdmissionModeTag {
|
|
6715
|
+
Fixed = 'Fixed',
|
|
6716
|
+
Reactive = 'Reactive',
|
|
6717
|
+
VramBudget = 'VramBudget'
|
|
6718
|
+
}
|
|
6719
|
+
|
|
6546
6720
|
/** Options for configuring an agent run. */
|
|
6547
6721
|
export interface JsAgentRunOptions {
|
|
6548
6722
|
/**
|
|
@@ -6625,6 +6799,29 @@ export interface JsArtifact {
|
|
|
6625
6799
|
customKind?: string
|
|
6626
6800
|
}
|
|
6627
6801
|
|
|
6802
|
+
/**
|
|
6803
|
+
* Worker-facing view of an assignment dispatched by the control plane.
|
|
6804
|
+
* JSON input is surfaced as a [`Buffer`] so handlers can decide whether
|
|
6805
|
+
* to decode (single-shot) or stream the bytes onward.
|
|
6806
|
+
*/
|
|
6807
|
+
export interface JsAssignment {
|
|
6808
|
+
/** Run identifier, rendered as a UUID string. */
|
|
6809
|
+
runId: string
|
|
6810
|
+
/** Symbolic workflow name. */
|
|
6811
|
+
workflowName: string
|
|
6812
|
+
/**
|
|
6813
|
+
* Optional workflow version. `None` lets the worker use whichever
|
|
6814
|
+
* version it has registered.
|
|
6815
|
+
*/
|
|
6816
|
+
workflowVersion?: number
|
|
6817
|
+
/** JSON-encoded initial input as raw bytes. */
|
|
6818
|
+
inputJson: Buffer
|
|
6819
|
+
/** Optional deadline in milliseconds. `None` = no timeout. */
|
|
6820
|
+
deadlineMs?: bigint
|
|
6821
|
+
/** 1-indexed attempt counter. Incremented on re-dispatch. */
|
|
6822
|
+
attempt: number
|
|
6823
|
+
}
|
|
6824
|
+
|
|
6628
6825
|
/** Audio content for multimodal messages. */
|
|
6629
6826
|
export interface JsAudioContent {
|
|
6630
6827
|
source: JsImageSource
|
|
@@ -6767,6 +6964,15 @@ export interface JsCitation {
|
|
|
6767
6964
|
metadata: any
|
|
6768
6965
|
}
|
|
6769
6966
|
|
|
6967
|
+
/**
|
|
6968
|
+
* Options bag passed to `ControlPlaneClient.connect`. The `mtls`
|
|
6969
|
+
* field, when present, swaps the connection into mTLS mode.
|
|
6970
|
+
*/
|
|
6971
|
+
export interface JsClientConnectOptions {
|
|
6972
|
+
/** mTLS configuration. `None` = plaintext. */
|
|
6973
|
+
mtls?: JsMtlsOptions
|
|
6974
|
+
}
|
|
6975
|
+
|
|
6770
6976
|
/** Options for a chat completion request. */
|
|
6771
6977
|
export interface JsCompletionOptions {
|
|
6772
6978
|
temperature?: number
|
|
@@ -6866,8 +7072,9 @@ export interface JsContentMetadata {
|
|
|
6866
7072
|
/**
|
|
6867
7073
|
* A single part in a multi-part message.
|
|
6868
7074
|
*
|
|
6869
|
-
* `partType` is one of `"text"`, `"image"`, `"audio"`, `"video"`.
|
|
6870
|
-
* matching field (`text`, `image`, `audio`, `video`)
|
|
7075
|
+
* `partType` is one of `"text"`, `"image"`, `"audio"`, `"video"`, `"file"`.
|
|
7076
|
+
* Set the matching field (`text`, `image`, `audio`, `video`, `file`)
|
|
7077
|
+
* accordingly.
|
|
6871
7078
|
*/
|
|
6872
7079
|
export interface JsContentPart {
|
|
6873
7080
|
partType: string
|
|
@@ -6875,6 +7082,7 @@ export interface JsContentPart {
|
|
|
6875
7082
|
image?: JsImageContent
|
|
6876
7083
|
audio?: JsAudioContent
|
|
6877
7084
|
video?: JsVideoContent
|
|
7085
|
+
file?: FileContent
|
|
6878
7086
|
}
|
|
6879
7087
|
|
|
6880
7088
|
/** Request to dereference a remote session ref. */
|
|
@@ -7331,6 +7539,19 @@ export interface JsModelStatus {
|
|
|
7331
7539
|
pool: string
|
|
7332
7540
|
}
|
|
7333
7541
|
|
|
7542
|
+
/**
|
|
7543
|
+
* PEM file paths for mTLS configuration. Used by
|
|
7544
|
+
* [`crate::controlplane::client::JsControlPlaneClient::connect`].
|
|
7545
|
+
*/
|
|
7546
|
+
export interface JsMtlsOptions {
|
|
7547
|
+
/** Path to the client certificate PEM file. */
|
|
7548
|
+
cert: string
|
|
7549
|
+
/** Path to the client private-key PEM file. */
|
|
7550
|
+
key: string
|
|
7551
|
+
/** Path to the CA PEM file used to authenticate the server. */
|
|
7552
|
+
ca: string
|
|
7553
|
+
}
|
|
7554
|
+
|
|
7334
7555
|
export interface JsMusicRequest {
|
|
7335
7556
|
prompt: string
|
|
7336
7557
|
durationSeconds?: number
|
|
@@ -7564,6 +7785,47 @@ export declare const enum JsRole {
|
|
|
7564
7785
|
Tool = 'tool'
|
|
7565
7786
|
}
|
|
7566
7787
|
|
|
7788
|
+
/** Event emitted during a run. Mirrors [`RunEvent`]. */
|
|
7789
|
+
export interface JsRunEvent {
|
|
7790
|
+
/** Run identifier, rendered as a UUID string. */
|
|
7791
|
+
runId: string
|
|
7792
|
+
/** Caller-supplied event type tag (e.g. `"step.completed"`). */
|
|
7793
|
+
eventType: string
|
|
7794
|
+
/** Free-form JSON payload. */
|
|
7795
|
+
data: any
|
|
7796
|
+
/** Wall-clock emission time in epoch milliseconds. */
|
|
7797
|
+
timestampMs: bigint
|
|
7798
|
+
}
|
|
7799
|
+
|
|
7800
|
+
/** Snapshot of a workflow run's state. Mirrors [`RunStateSnapshot`]. */
|
|
7801
|
+
export interface JsRunStateSnapshot {
|
|
7802
|
+
/** Run identifier, rendered as a UUID string. */
|
|
7803
|
+
runId: string
|
|
7804
|
+
/** Current status. */
|
|
7805
|
+
status: JsRunStatus
|
|
7806
|
+
/** Wall-clock submission time in epoch milliseconds. */
|
|
7807
|
+
startedAtMs: bigint
|
|
7808
|
+
/** Wall-clock completion time, `None` until terminal. */
|
|
7809
|
+
completedAtMs?: bigint
|
|
7810
|
+
/** `Some(node_id)` once the run has been routed to a worker. */
|
|
7811
|
+
assignedTo?: string
|
|
7812
|
+
/** Wall-clock of the most recent event for this run, if any. */
|
|
7813
|
+
lastEventAtMs?: bigint
|
|
7814
|
+
/** Terminal output JSON value if `status == 'Completed'`. */
|
|
7815
|
+
output?: any
|
|
7816
|
+
/** Error message if `status == 'Failed'`. */
|
|
7817
|
+
error?: string
|
|
7818
|
+
}
|
|
7819
|
+
|
|
7820
|
+
/** JS-facing run status. Mirrors [`RunStatus`]. */
|
|
7821
|
+
export declare const enum JsRunStatus {
|
|
7822
|
+
Pending = 'Pending',
|
|
7823
|
+
Running = 'Running',
|
|
7824
|
+
Completed = 'Completed',
|
|
7825
|
+
Failed = 'Failed',
|
|
7826
|
+
Cancelled = 'Cancelled'
|
|
7827
|
+
}
|
|
7828
|
+
|
|
7567
7829
|
export interface JsSpeechRequest {
|
|
7568
7830
|
text: string
|
|
7569
7831
|
voice?: string
|
|
@@ -7642,6 +7904,42 @@ export interface JsStreamChunk {
|
|
|
7642
7904
|
artifacts: Array<JsArtifact>
|
|
7643
7905
|
}
|
|
7644
7906
|
|
|
7907
|
+
/**
|
|
7908
|
+
* Options bag for
|
|
7909
|
+
* [`crate::controlplane::client::JsControlPlaneClient::submit_workflow`].
|
|
7910
|
+
*/
|
|
7911
|
+
export interface JsSubmitWorkflowOptions {
|
|
7912
|
+
/** Symbolic name of the workflow to run. */
|
|
7913
|
+
workflowName: string
|
|
7914
|
+
/** JSON-serializable initial input. */
|
|
7915
|
+
input: any
|
|
7916
|
+
/** Optional workflow version. `None` = latest. */
|
|
7917
|
+
workflowVersion?: number
|
|
7918
|
+
/**
|
|
7919
|
+
* Required tags. Each `key=value` (or `key=*`) is AND'd. `None`
|
|
7920
|
+
* means no tag predicate.
|
|
7921
|
+
*/
|
|
7922
|
+
requiredTags?: Array<string>
|
|
7923
|
+
/** Optional dedupe key for at-most-one-run-per-window semantics. */
|
|
7924
|
+
idempotencyKey?: string
|
|
7925
|
+
/** Optional deadline in milliseconds from submission. */
|
|
7926
|
+
deadlineMs?: bigint
|
|
7927
|
+
/**
|
|
7928
|
+
* If `true`, queue the submission until a matching worker appears.
|
|
7929
|
+
* Defaults to `false`.
|
|
7930
|
+
*/
|
|
7931
|
+
waitForWorker?: boolean
|
|
7932
|
+
}
|
|
7933
|
+
|
|
7934
|
+
/**
|
|
7935
|
+
* Options bag for
|
|
7936
|
+
* [`crate::controlplane::client::JsControlPlaneClient::subscribe_all`].
|
|
7937
|
+
*/
|
|
7938
|
+
export interface JsSubscribeAllOptions {
|
|
7939
|
+
/** Tag predicates the events must match. */
|
|
7940
|
+
requiredTags?: Array<string>
|
|
7941
|
+
}
|
|
7942
|
+
|
|
7645
7943
|
/** Request to invoke a sub-workflow on a remote peer. */
|
|
7646
7944
|
export interface JsSubWorkflowRequest {
|
|
7647
7945
|
/** Symbolic name of the workflow to invoke on the remote peer. */
|
|
@@ -7918,6 +8216,37 @@ export interface JsWhisperOptions {
|
|
|
7918
8216
|
cacheDir?: string
|
|
7919
8217
|
}
|
|
7920
8218
|
|
|
8219
|
+
/**
|
|
8220
|
+
* Capability advertised by a worker at handshake time. Mirrors
|
|
8221
|
+
* [`blazen_core::distributed::WorkerCapability`].
|
|
8222
|
+
*/
|
|
8223
|
+
export interface JsWorkerCapability {
|
|
8224
|
+
/** Capability tag, e.g. `"workflow:summarize"`. */
|
|
8225
|
+
kind: string
|
|
8226
|
+
/**
|
|
8227
|
+
* Capability version. Workers and orchestrators only match when both
|
|
8228
|
+
* values agree.
|
|
8229
|
+
*/
|
|
8230
|
+
version: number
|
|
8231
|
+
}
|
|
8232
|
+
|
|
8233
|
+
/**
|
|
8234
|
+
* Summary of a connected worker returned by
|
|
8235
|
+
* [`crate::controlplane::client::JsControlPlaneClient::list_workers`].
|
|
8236
|
+
*/
|
|
8237
|
+
export interface JsWorkerInfo {
|
|
8238
|
+
/** Stable identifier of the worker. */
|
|
8239
|
+
nodeId: string
|
|
8240
|
+
/** Capabilities advertised by this worker at handshake. */
|
|
8241
|
+
capabilities: Array<JsWorkerCapability>
|
|
8242
|
+
/** Free-form `key=value` tags this worker advertised. */
|
|
8243
|
+
tags: Record<string, string>
|
|
8244
|
+
/** Last reported in-flight assignment count. */
|
|
8245
|
+
inFlight: number
|
|
8246
|
+
/** Wall-clock connection time in epoch milliseconds. */
|
|
8247
|
+
connectedAtMs: bigint
|
|
8248
|
+
}
|
|
8249
|
+
|
|
7921
8250
|
/**
|
|
7922
8251
|
* Plain-object payload accepted by `WorkflowCheckpoint.create()` for
|
|
7923
8252
|
* constructing a checkpoint from JS.
|
|
@@ -7994,11 +8323,8 @@ export interface LlmPayload {
|
|
|
7994
8323
|
* `kind: "provider_raw"`.
|
|
7995
8324
|
*/
|
|
7996
8325
|
value?: any
|
|
7997
|
-
/**
|
|
7998
|
-
|
|
7999
|
-
* Required for `kind: "parts"`.
|
|
8000
|
-
*/
|
|
8001
|
-
parts?: any
|
|
8326
|
+
/** Multimodal content parts. Required for `kind: "parts"`. */
|
|
8327
|
+
parts?: Array<JsContentPart>
|
|
8002
8328
|
/** Provider id string. Required for `kind: "provider_raw"`. */
|
|
8003
8329
|
provider?: string
|
|
8004
8330
|
}
|
|
@@ -9055,6 +9381,17 @@ export type ImageSource = JsImageSource
|
|
|
9055
9381
|
export type ContentHandle = JsContentHandle
|
|
9056
9382
|
export type ContentMetadata = JsContentMetadata
|
|
9057
9383
|
export type ContentKind = JsContentKind
|
|
9384
|
+
export type WorkerCapability = JsWorkerCapability
|
|
9385
|
+
export type AdmissionMode = JsAdmissionMode
|
|
9386
|
+
export type Assignment = JsAssignment
|
|
9387
|
+
export type RunStatus = JsRunStatus
|
|
9388
|
+
export type RunStateSnapshot = JsRunStateSnapshot
|
|
9389
|
+
export type RunEvent = JsRunEvent
|
|
9390
|
+
export type WorkerInfo = JsWorkerInfo
|
|
9391
|
+
export type MtlsOptions = JsMtlsOptions
|
|
9392
|
+
export type ClientConnectOptions = JsClientConnectOptions
|
|
9393
|
+
export type SubmitWorkflowOptions = JsSubmitWorkflowOptions
|
|
9394
|
+
export type SubscribeAllOptions = JsSubscribeAllOptions
|
|
9058
9395
|
|
|
9059
9396
|
// --- post-build: ContentBody / ContentHint helper types ---
|
|
9060
9397
|
/**
|
package/index.js
CHANGED
|
@@ -584,6 +584,8 @@ module.exports.AnthropicProvider = nativeBinding.AnthropicProvider
|
|
|
584
584
|
module.exports.JsAnthropicProvider = nativeBinding.JsAnthropicProvider
|
|
585
585
|
module.exports.ApiProtocol = nativeBinding.ApiProtocol
|
|
586
586
|
module.exports.JsApiProtocol = nativeBinding.JsApiProtocol
|
|
587
|
+
module.exports.AssignmentContext = nativeBinding.AssignmentContext
|
|
588
|
+
module.exports.JsAssignmentContext = nativeBinding.JsAssignmentContext
|
|
587
589
|
module.exports.AudioMusicProviderDefaults = nativeBinding.AudioMusicProviderDefaults
|
|
588
590
|
module.exports.JsAudioMusicProviderDefaults = nativeBinding.JsAudioMusicProviderDefaults
|
|
589
591
|
module.exports.AudioSpeechProviderDefaults = nativeBinding.AudioSpeechProviderDefaults
|
|
@@ -640,6 +642,12 @@ module.exports.ContentStore = nativeBinding.ContentStore
|
|
|
640
642
|
module.exports.JsContentStore = nativeBinding.JsContentStore
|
|
641
643
|
module.exports.Context = nativeBinding.Context
|
|
642
644
|
module.exports.JsContext = nativeBinding.JsContext
|
|
645
|
+
module.exports.ControlPlaneClient = nativeBinding.ControlPlaneClient
|
|
646
|
+
module.exports.JsControlPlaneClient = nativeBinding.JsControlPlaneClient
|
|
647
|
+
module.exports.ControlPlaneWorker = nativeBinding.ControlPlaneWorker
|
|
648
|
+
module.exports.JsControlPlaneWorker = nativeBinding.JsControlPlaneWorker
|
|
649
|
+
module.exports.ControlPlaneWorkerConfig = nativeBinding.ControlPlaneWorkerConfig
|
|
650
|
+
module.exports.JsControlPlaneWorkerConfig = nativeBinding.JsControlPlaneWorkerConfig
|
|
643
651
|
module.exports.CustomProvider = nativeBinding.CustomProvider
|
|
644
652
|
module.exports.JsCustomProvider = nativeBinding.JsCustomProvider
|
|
645
653
|
module.exports.DeepSeekProvider = nativeBinding.DeepSeekProvider
|
|
@@ -925,6 +933,7 @@ module.exports.initPrometheus = nativeBinding.initPrometheus
|
|
|
925
933
|
module.exports.internEventType = nativeBinding.internEventType
|
|
926
934
|
module.exports.JoinStrategy = nativeBinding.JoinStrategy
|
|
927
935
|
module.exports.JsJoinStrategy = nativeBinding.JsJoinStrategy
|
|
936
|
+
module.exports.JsAdmissionModeTag = nativeBinding.JsAdmissionModeTag
|
|
928
937
|
module.exports.JsAuthMethod = nativeBinding.JsAuthMethod
|
|
929
938
|
module.exports.JsCacheStrategy = nativeBinding.JsCacheStrategy
|
|
930
939
|
module.exports.JsContentKind = nativeBinding.JsContentKind
|
|
@@ -932,6 +941,7 @@ module.exports.JsDiffusionScheduler = nativeBinding.JsDiffusionScheduler
|
|
|
932
941
|
module.exports.JsFalLlmEndpointKind = nativeBinding.JsFalLlmEndpointKind
|
|
933
942
|
module.exports.JsJobStatus = nativeBinding.JsJobStatus
|
|
934
943
|
module.exports.JsRole = nativeBinding.JsRole
|
|
944
|
+
module.exports.JsRunStatus = nativeBinding.JsRunStatus
|
|
935
945
|
module.exports.JsWhisperModel = nativeBinding.JsWhisperModel
|
|
936
946
|
module.exports.LlamaCppChatRole = nativeBinding.LlamaCppChatRole
|
|
937
947
|
module.exports.JsLlamaCppChatRole = nativeBinding.JsLlamaCppChatRole
|
|
@@ -1032,6 +1042,67 @@ module.exports.videoInput = nativeBinding.videoInput
|
|
|
1032
1042
|
}
|
|
1033
1043
|
}
|
|
1034
1044
|
|
|
1045
|
+
// Specialised handling for the agent entrypoints. The user's
|
|
1046
|
+
// `toolHandler` argument must be wrapped to envelope-format thrown
|
|
1047
|
+
// errors (see `wrapToolHandlerForCallerErrors` in error-classes.js);
|
|
1048
|
+
// `enrichError` then re-throws the original instance after the agent
|
|
1049
|
+
// loop rejects with the `__BLAZEN_CALLER_ERROR__` sentinel. The
|
|
1050
|
+
// generic `wrap()` loop below is skipped for these via the
|
|
1051
|
+
// `__blazenCallerErrorWrapped` marker.
|
|
1052
|
+
const { wrapToolHandlerForCallerErrors, callerErrorStash } = errorClasses
|
|
1053
|
+
const AGENT_ENTRYPOINTS = ['runAgent', 'runAgentWithCallback']
|
|
1054
|
+
for (const fnName of AGENT_ENTRYPOINTS) {
|
|
1055
|
+
const orig = module.exports[fnName]
|
|
1056
|
+
if (typeof orig !== 'function') continue
|
|
1057
|
+
// toolHandler is positional arg index 3 for both runAgent and
|
|
1058
|
+
// runAgentWithCallback in the current TS signatures.
|
|
1059
|
+
const TOOL_HANDLER_ARG_INDEX = 3
|
|
1060
|
+
const wrapped = function blazenAgentEntrypoint(...args) {
|
|
1061
|
+
if (args.length > TOOL_HANDLER_ARG_INDEX) {
|
|
1062
|
+
const userHandler = args[TOOL_HANDLER_ARG_INDEX]
|
|
1063
|
+
if (typeof userHandler === 'function') {
|
|
1064
|
+
args[TOOL_HANDLER_ARG_INDEX] = wrapToolHandlerForCallerErrors(userHandler)
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
// Track stash entries created during this run so we can
|
|
1068
|
+
// garbage-collect any that the agent loop swallowed (e.g.
|
|
1069
|
+
// succeeded after a handler threw, or the loop ended before the
|
|
1070
|
+
// napi side surfaced the caller error).
|
|
1071
|
+
const stashSnapshot = new Set(callerErrorStash.keys())
|
|
1072
|
+
const cleanupNewStash = () => {
|
|
1073
|
+
for (const key of callerErrorStash.keys()) {
|
|
1074
|
+
if (!stashSnapshot.has(key)) {
|
|
1075
|
+
callerErrorStash.delete(key)
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
try {
|
|
1080
|
+
const result = orig.apply(this, args)
|
|
1081
|
+
if (result && typeof result.then === 'function') {
|
|
1082
|
+
return result.then(
|
|
1083
|
+
(v) => {
|
|
1084
|
+
cleanupNewStash()
|
|
1085
|
+
return v
|
|
1086
|
+
},
|
|
1087
|
+
(e) => {
|
|
1088
|
+
const enriched = enrichError(e)
|
|
1089
|
+
cleanupNewStash()
|
|
1090
|
+
throw enriched
|
|
1091
|
+
},
|
|
1092
|
+
)
|
|
1093
|
+
}
|
|
1094
|
+
cleanupNewStash()
|
|
1095
|
+
return result
|
|
1096
|
+
} catch (e) {
|
|
1097
|
+
const enriched = enrichError(e)
|
|
1098
|
+
cleanupNewStash()
|
|
1099
|
+
throw enriched
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
wrapped.__blazenCallerErrorWrapped = true
|
|
1103
|
+
module.exports[fnName] = wrapped
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1035
1106
|
// Wrap every top-level export. Distinguish functions (call wrap) from
|
|
1036
1107
|
// constructors (call patchPrototype). Heuristic: a constructor has a
|
|
1037
1108
|
// `prototype` object with own properties beyond `constructor`. When
|
|
@@ -1045,6 +1116,8 @@ module.exports.videoInput = nativeBinding.videoInput
|
|
|
1045
1116
|
if (typeof orig !== 'function') continue
|
|
1046
1117
|
// Skip the typed-error classes we are about to install.
|
|
1047
1118
|
if (Object.prototype.hasOwnProperty.call(errorClasses, key)) continue
|
|
1119
|
+
// Skip the agent entrypoints we already specialised above.
|
|
1120
|
+
if (orig.__blazenCallerErrorWrapped) continue
|
|
1048
1121
|
if (orig.prototype && typeof orig.prototype === 'object') {
|
|
1049
1122
|
patchPrototype(orig)
|
|
1050
1123
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blazen",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Blazen - Event-driven AI workflow framework for Node.js/TypeScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -88,13 +88,13 @@
|
|
|
88
88
|
"verbose": true
|
|
89
89
|
},
|
|
90
90
|
"optionalDependencies": {
|
|
91
|
-
"@blazen-dev/blazen-linux-x64-gnu": "0.5.
|
|
92
|
-
"@blazen-dev/blazen-linux-x64-musl": "0.5.
|
|
93
|
-
"@blazen-dev/blazen-linux-arm64-gnu": "0.5.
|
|
94
|
-
"@blazen-dev/blazen-linux-arm64-musl": "0.5.
|
|
95
|
-
"@blazen-dev/blazen-darwin-arm64": "0.5.
|
|
96
|
-
"@blazen-dev/blazen-win32-x64-msvc": "0.5.
|
|
97
|
-
"@blazen-dev/blazen-wasm32-wasi": "0.5.
|
|
91
|
+
"@blazen-dev/blazen-linux-x64-gnu": "0.5.4",
|
|
92
|
+
"@blazen-dev/blazen-linux-x64-musl": "0.5.4",
|
|
93
|
+
"@blazen-dev/blazen-linux-arm64-gnu": "0.5.4",
|
|
94
|
+
"@blazen-dev/blazen-linux-arm64-musl": "0.5.4",
|
|
95
|
+
"@blazen-dev/blazen-darwin-arm64": "0.5.4",
|
|
96
|
+
"@blazen-dev/blazen-win32-x64-msvc": "0.5.4",
|
|
97
|
+
"@blazen-dev/blazen-wasm32-wasi": "0.5.4"
|
|
98
98
|
},
|
|
99
99
|
"scripts": {
|
|
100
100
|
"build": "napi build --release --platform --features local-all,langfuse --js index.js && node scripts/post-build.mjs",
|