///
The Quicksilver SDK's fluent Domain-Specific Language (DSL) is built upon powerful builders that allow developers to express complex financial logic and product definitions in an elegant, type-safe, a
63 views
~63 views from guests
Guest views are estimated from total page views. These include anonymous visitors and users who weren't logged in when they viewed the page.
The Quicksilver SDK's fluent Domain-Specific Language (DSL) is built upon powerful builders that allow developers to express complex financial logic and product definitions in an elegant, type-safe, and highly readable manner. These builders abstract away the underlying API payload construction, focusing on expressive, chainable methods.
This section details the primary DSL builders: ConditionBuilder, ProductBuilder, and Action (with ActionBuilder).
ConditionBuilderThe ConditionBuilder is used to define intricate conditional logic for transactions and products, enabling "when-then-otherwise" rules. It provides a fluent interface for constructing a sequence of conditions and their corresponding actions.
Instantiation:
To start building conditional logic, use the factory method on the QuicksilverClient:
Methods:
when(trigger: QuickSilverEvent | ((ctx: any) => boolean), predicate?: (ctx: any) => boolean): thisDefines a trigger for a set of actions. This method initiates a new conditional block.
trigger: The event that triggers the condition (e.g., QuickSilverEvent.MilestoneApproved) or a custom JavaScript function that evaluates against the event context (ctx).predicate: An optional refining predicate function that provides additional context-based filtering for the trigger.this (for chaining).then(...actions: Action[]): thisDefines the action(s) to take when the preceding when condition is met. This method must be called immediately after when().
actions: One or more Action instances to be executed.this (for chaining).otherwise(...actions: Action[]): thisDefines a fallback action or set of actions if none of the when conditions are met. This acts as a default rule.
actions: One or more Action instances to be executed.this (for chaining).toJSON(): objectSerializes the entire conditional logic (all when/then blocks and otherwise actions) into a JSON object that the Quicksilver Engine API expects. This method typically converts predicate functions into internal representations for API transmission.
getConditions(): Condition[]Returns the raw array of compiled conditions, including their triggers, predicates, and associated actions. This is primarily for internal SDK use or advanced debugging, offering a direct view of the structured conditions.
Example:
ProductBuilder (aliased as Product)The ProductBuilder allows you to define programmable products and services, encapsulating pricing, service level guarantees, multi-agent workflows, and associated conditional logic. This builder directly represents the Product primitive in the SDK, meaning no separate build() method is required; the builder itself is the final product object.
Instantiation:
To define a new product, use the factory method on the QuicksilverClient:
Methods:
constructor(id: string)Initializes a new ProductBuilder instance with a unique identifier.
id: A unique string identifier for the product.charge(rate: number, unit: string, currency: Currency = 'USD'): thisDefines a unit-based pricing model for the product.
rate: The cost per unit.unit: The unit of charge (e.g., 'per_word', 'per_transaction', 'monthly').currency: The currency of the charge (defaults to 'USD').this (for chaining).stream(rate: number, unit: 'per_second' | 'per_minute', currency: Currency = 'USD'): thisDefines a streaming pricing model for the product.
rate: The cost per stream unit.unit: The unit of streaming charge (e.g., 'per_second', 'per_minute').currency: The currency of the stream (defaults to 'USD').this (for chaining).guarantee(guarantees: Record<string, any>): thisAdds service level guarantees or other contractual assurances for the product.
guarantees: An object where keys are guarantee names (e.g., 'accuracy', 'turnaround') and values are their specifications.this (for chaining).stage(name: string, config: { delegateTo: string, charge: number }): thisDefines a stage within a multi-agent workflow for this product.
name: The name of the stage (e.g., 'research', 'writing').config: An object specifying delegateTo (the ID of the agent handling this stage) and charge (the cost associated with this stage).this (for chaining).to(accountId: string): thisSets the default recipient account for payments related to this product.
accountId: The ID of the receiving account.this (for chaining).from(accountId: string): thisSets the default source account for payments related to this product.
accountId: The ID of the paying account.this (for chaining).currency(code: Currency): thisSets the primary currency for the product's pricing.
code: The currency code (e.g., 'USD', 'EUR').this (for chaining).withConditions(conditionBuilder: ConditionBuilder): thisAttaches a pre-defined set of conditional logic to the product.
conditionBuilder: An instance of ConditionBuilder containing the conditional logic.this (for chaining).withActions(...actionBuilders: Action[]): thisAttaches additional actions that should be performed when the product is utilized.
actionBuilders: One or more Action instances.this (for chaining).meta(metadata: Record<string, any>): thisAdds custom metadata to the product definition.
metadata: An object containing arbitrary key-value pairs.this (for chaining).getPricing(): anyRetrieves the currently defined pricing model for the product.
getGuarantees(): anyRetrieves the currently defined service level guarantees.
getWorkflow(): any[]Retrieves the list of defined workflow stages for the product.
toJSON(): objectSerializes the complete product definition into a JSON object that the Quicksilver Engine API expects.
Example:
Action and ActionBuilderThe Action class serves as a factory for creating specific action types, while ActionBuilder provides a fluent interface for configuring more complex actions like fund releases. These actions are typically used within ConditionBuilder to define what happens when a condition is met.
Instantiation:
Action instances are created using its static factory methods. For fluent configuration of certain actions, these methods return an ActionBuilder.
Action Static Factory Methods:
static release(amount: number, currency: Currency = 'USD'): ActionBuilderCreates an action to release a specified amount of funds. This method returns an ActionBuilder to allow for further fluent configuration like specifying the recipient.
amount: The amount of money to release.currency: The currency of the amount (defaults to 'USD').ActionBuilder (for chaining .to(), .withMeta()).static notify(account: any, message: string): ActionCreates a simple notification action to inform a specific account.
account: The recipient account's ID or object.message: The notification message.Action.static hold(message: string): ActionCreates an action to place funds on hold or pause execution, providing a reason.
message: A message explaining why the funds are on hold.Action.static custom(type: string, data: Record<string, any>): ActionCreates a custom action with an arbitrary type and data payload.
type: A string identifying the custom action.data: An object containing the custom data for the action.Action.ActionBuilder Methods (returned by Action.release()):
to(account: any): ActionBuilderSpecifies the target account for a release action.
account: The recipient account's ID or object.ActionBuilder (for chaining).withMeta(meta: Record<string, any>): ActionBuilderAdds metadata to the action.
meta: An object containing arbitrary key-value pairs.ActionBuilder (for chaining).toJSON(): objectSerializes the action into a JSON object that the Quicksilver Engine API expects.
Example:
toJSON() and getConditions()The fluent builders (ConditionBuilder, ProductBuilder, ActionBuilder) are designed to construct complex data structures in an intuitive, programmatic way. However, these in-memory objects need to be transformed into a standardized JSON format for transmission to the Quicksilver Engine API. This is the role of the toJSON() method present on all builders and Action instances.
toJSON(): object: This method converts the builder's internal state into a plain JavaScript object (which is then typically stringified to JSON) that precisely matches the API's expected payload structure. It hides the complexity of mapping fluent calls to the wire format, ensuring consistency and correctness. For instance, a ConditionBuilder's toJSON() will output an object containing an array of conditions and an otherwise array, where each action within these arrays will also have its toJSON() method called.
getConditions(): Condition[]: Specific to the ConditionBuilder, this method returns the internal array of Condition objects. While toJSON() provides the API-ready representation (often converting functions to string identifiers if needed), getConditions() provides the raw, structured conditions as managed by the builder, including any predicate functions in their original form. This is useful for inspection or cases where the raw object structure is preferred over the API's wire format.
By using these methods, developers can build complex logic with ease, relying on the SDK to handle the underlying data serialization required by the Quicksilver Engine API.
[SDK Architecture]