wauldo 0.7.2 → 0.8.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/README.md +33 -0
- package/dist/index.d.mts +172 -1
- package/dist/index.d.ts +172 -1
- package/dist/index.js +233 -2
- package/dist/index.mjs +229 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -116,6 +116,39 @@ console.log(result.action); // "block"
|
|
|
116
116
|
console.log(result.claims[0].reason); // "numerical_mismatch"
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
+
### Deployed Agents — create, run, stream
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { AgentsClient } from 'wauldo';
|
|
123
|
+
|
|
124
|
+
const agents = new AgentsClient({
|
|
125
|
+
baseUrl: 'https://api.wauldo.com',
|
|
126
|
+
apiKey: 'YOUR_API_KEY',
|
|
127
|
+
tenant: 'my-tenant',
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const agent = await agents.create({
|
|
131
|
+
name: 'support-bot',
|
|
132
|
+
description: 'Answers refund questions',
|
|
133
|
+
wauldoToml: `[agent]\nname = "support-bot"\n[model]\nprovider = "openrouter"\nname = "auto"`,
|
|
134
|
+
preset: 'general_task', // or 'rust_backend_architect', 'rag_data_engineer', ...
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const run = await agents.run(agent.id, 'Can I return a shirt 30 days after purchase?');
|
|
138
|
+
|
|
139
|
+
// Stream reasoning live as each workflow state completes
|
|
140
|
+
for await (const event of agents.streamTask(run.task_id)) {
|
|
141
|
+
console.log(` ${event.state_name}: ${event.duration_ms}ms (${event.completion_tokens} tok)`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Or poll for the final verified result
|
|
145
|
+
const task = await agents.waitForTask(run.task_id, { timeoutMs: 120_000 });
|
|
146
|
+
console.log(task.result); // The answer
|
|
147
|
+
console.log(task.verification?.verdict); // SAFE | UNVERIFIED | BLOCK | …
|
|
148
|
+
console.log(task.verification?.trust_score); // 0.0 – 1.0
|
|
149
|
+
console.log(task.verification?.message); // Human-readable context when non-SAFE
|
|
150
|
+
```
|
|
151
|
+
|
|
119
152
|
### Chat (OpenAI-compatible)
|
|
120
153
|
|
|
121
154
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -644,4 +644,175 @@ declare class ToolNotFoundError extends WauldoError {
|
|
|
644
644
|
constructor(toolName: string);
|
|
645
645
|
}
|
|
646
646
|
|
|
647
|
-
|
|
647
|
+
interface AgentsClientConfig {
|
|
648
|
+
baseUrl: string;
|
|
649
|
+
apiKey?: string;
|
|
650
|
+
/** Tenant identifier forwarded via x-rapidapi-user header. */
|
|
651
|
+
tenant?: string;
|
|
652
|
+
/** Per-request timeout in ms. Default 120_000. */
|
|
653
|
+
timeoutMs?: number;
|
|
654
|
+
}
|
|
655
|
+
interface DeployedAgent {
|
|
656
|
+
id: string;
|
|
657
|
+
tenant_id: string;
|
|
658
|
+
name: string;
|
|
659
|
+
description: string;
|
|
660
|
+
wauldo_toml: string;
|
|
661
|
+
agents_md?: string;
|
|
662
|
+
mcp_json?: string;
|
|
663
|
+
model_provider: string;
|
|
664
|
+
model_name: string;
|
|
665
|
+
preset?: string;
|
|
666
|
+
created_at: number;
|
|
667
|
+
updated_at: number;
|
|
668
|
+
}
|
|
669
|
+
interface CreateAgentInput {
|
|
670
|
+
name: string;
|
|
671
|
+
wauldoToml: string;
|
|
672
|
+
description?: string;
|
|
673
|
+
agentsMd?: string;
|
|
674
|
+
mcpJson?: string;
|
|
675
|
+
preset?: string;
|
|
676
|
+
}
|
|
677
|
+
interface UpdateAgentPatch {
|
|
678
|
+
description?: string;
|
|
679
|
+
wauldoToml?: string;
|
|
680
|
+
agentsMd?: string;
|
|
681
|
+
mcpJson?: string;
|
|
682
|
+
preset?: string;
|
|
683
|
+
}
|
|
684
|
+
interface AgentListResponse {
|
|
685
|
+
agents: DeployedAgent[];
|
|
686
|
+
pagination: {
|
|
687
|
+
total: number;
|
|
688
|
+
limit: number;
|
|
689
|
+
offset: number;
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
interface AgentRunResponse {
|
|
693
|
+
task_id: string;
|
|
694
|
+
agent_id: string;
|
|
695
|
+
status: string;
|
|
696
|
+
created_at: number;
|
|
697
|
+
}
|
|
698
|
+
interface A2aResponse {
|
|
699
|
+
task_id: string;
|
|
700
|
+
agent_id: string;
|
|
701
|
+
trace: string[];
|
|
702
|
+
depth: number;
|
|
703
|
+
status: string;
|
|
704
|
+
}
|
|
705
|
+
/** Verification verdict returned on completed tasks. */
|
|
706
|
+
type Verdict = "SAFE" | "UNCERTAIN" | "PARTIAL" | "BLOCK" | "CONFLICT" | "UNVERIFIED";
|
|
707
|
+
/** Task lifecycle status. */
|
|
708
|
+
type TaskStatus = "queued" | "running" | "completed" | "failed" | "cancelled";
|
|
709
|
+
/** A single verified claim from an agent output. */
|
|
710
|
+
interface TaskClaim {
|
|
711
|
+
text: string;
|
|
712
|
+
supported: boolean;
|
|
713
|
+
confidence: number;
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* Verification block attached to completed tasks. When
|
|
717
|
+
* `verification_source === "prompt_only"` the `confidence` and
|
|
718
|
+
* `hallucination_rate` fields reflect self-consistency only; rely on
|
|
719
|
+
* `verdict` + `trust_score` + `message` as authoritative.
|
|
720
|
+
*/
|
|
721
|
+
interface TaskVerification {
|
|
722
|
+
verdict: Verdict;
|
|
723
|
+
hallucination_rate: number;
|
|
724
|
+
confidence: number;
|
|
725
|
+
trust_score: number;
|
|
726
|
+
verification_source: string;
|
|
727
|
+
claims: TaskClaim[];
|
|
728
|
+
verification_retries: number;
|
|
729
|
+
/** Human-readable context for non-SAFE verdicts. */
|
|
730
|
+
message?: string | null;
|
|
731
|
+
sources_cited?: number[];
|
|
732
|
+
stripped_claims?: string[];
|
|
733
|
+
}
|
|
734
|
+
/** Full task record returned by `GET /v1/tasks/:id`. */
|
|
735
|
+
interface Task {
|
|
736
|
+
task_id: string;
|
|
737
|
+
tenant_id: string;
|
|
738
|
+
status: TaskStatus;
|
|
739
|
+
prompt: string;
|
|
740
|
+
created_at: number;
|
|
741
|
+
updated_at: number;
|
|
742
|
+
preset?: string | null;
|
|
743
|
+
result?: string | null;
|
|
744
|
+
error?: string | null;
|
|
745
|
+
partial_result?: string | null;
|
|
746
|
+
verification?: TaskVerification | null;
|
|
747
|
+
journal?: Record<string, unknown> | null;
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Single event yielded by `GET /v1/tasks/:id/stream`. Each SSE `data:`
|
|
751
|
+
* line is a JSON-serialised StateTransition emitted when a workflow
|
|
752
|
+
* state completes.
|
|
753
|
+
*/
|
|
754
|
+
interface StateTransition {
|
|
755
|
+
state_name: string;
|
|
756
|
+
to_state?: string | null;
|
|
757
|
+
condition: string;
|
|
758
|
+
raw_output: string;
|
|
759
|
+
validation_notes: string[];
|
|
760
|
+
timestamp: number;
|
|
761
|
+
success: boolean;
|
|
762
|
+
retry_count: number;
|
|
763
|
+
duration_ms: number;
|
|
764
|
+
prompt_tokens: number;
|
|
765
|
+
completion_tokens: number;
|
|
766
|
+
repair_count: number;
|
|
767
|
+
cache_hit: boolean;
|
|
768
|
+
}
|
|
769
|
+
declare function isTerminalStatus(s: TaskStatus | string): boolean;
|
|
770
|
+
declare class HttpError extends Error {
|
|
771
|
+
status: number;
|
|
772
|
+
statusText: string;
|
|
773
|
+
body: string;
|
|
774
|
+
constructor(status: number, statusText: string, body: string);
|
|
775
|
+
}
|
|
776
|
+
declare class AgentsClient {
|
|
777
|
+
private readonly config;
|
|
778
|
+
constructor(config: AgentsClientConfig);
|
|
779
|
+
private headers;
|
|
780
|
+
private request;
|
|
781
|
+
create(input: CreateAgentInput): Promise<DeployedAgent>;
|
|
782
|
+
list(limit?: number, offset?: number): Promise<AgentListResponse>;
|
|
783
|
+
get(agentId: string): Promise<DeployedAgent>;
|
|
784
|
+
update(agentId: string, patch: UpdateAgentPatch): Promise<DeployedAgent>;
|
|
785
|
+
delete(agentId: string): Promise<void>;
|
|
786
|
+
run(agentId: string, input: string, verificationMode?: "strict" | "balanced" | "permissive"): Promise<AgentRunResponse>;
|
|
787
|
+
a2aInvoke(agentId: string, input: string, trace?: string[], verificationMode?: "strict" | "balanced" | "permissive"): Promise<A2aResponse>;
|
|
788
|
+
/** `GET /v1/tasks/:id` — fetch the current state of a task. */
|
|
789
|
+
getTask(taskId: string): Promise<Task>;
|
|
790
|
+
/** `DELETE /v1/tasks/:id` — cancel a queued or running task. */
|
|
791
|
+
cancelTask(taskId: string): Promise<void>;
|
|
792
|
+
/**
|
|
793
|
+
* Poll `getTask` until the task reaches a terminal status. Resolves
|
|
794
|
+
* with the final Task snapshot. Rejects with `Error("timeout")` if
|
|
795
|
+
* the task is still running after `timeoutMs`. Use `streamTask` when
|
|
796
|
+
* you need event-by-event progress instead of a single final state.
|
|
797
|
+
*/
|
|
798
|
+
waitForTask(taskId: string, opts?: {
|
|
799
|
+
timeoutMs?: number;
|
|
800
|
+
pollIntervalMs?: number;
|
|
801
|
+
}): Promise<Task>;
|
|
802
|
+
/**
|
|
803
|
+
* Subscribe to `GET /v1/tasks/:id/stream` and yield typed
|
|
804
|
+
* StateTransition events as each workflow state completes. The
|
|
805
|
+
* generator closes when the upstream stream closes (task reached
|
|
806
|
+
* terminal status) or on connection error.
|
|
807
|
+
*
|
|
808
|
+
* @example
|
|
809
|
+
* ```ts
|
|
810
|
+
* for await (const event of agents.streamTask(run.task_id)) {
|
|
811
|
+
* console.log(event.state_name, event.duration_ms);
|
|
812
|
+
* }
|
|
813
|
+
* ```
|
|
814
|
+
*/
|
|
815
|
+
streamTask(taskId: string): AsyncGenerator<StateTransition>;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
export { type A2aResponse, AgentClient, type AgentListResponse, type AgentRunResponse, AgentsClient, type AgentsClientConfig, type CallToolResponse, type ChatChoice, type ChatClientLike, type ChatMessage, type ChatRequest, type ChatResponse, type ChatUsage, type Chunk, type ChunkResult, type ClientOptions, type Concept, type ConceptResult, ConnectionError, Conversation, type CreateAgentInput, type DeployedAgent, type DetailLevel, type EmbeddingData, type EmbeddingResponse, type EmbeddingUsage, type GraphNode, type GuardClaim, type GuardMode, type GuardResponse, HttpClient, type HttpClientConfig, HttpError, type KnowledgeGraphResult, type LogLevel, MockHttpClient, type ModelInfo, type ModelList, type OrchestratorResponse, type PlanOptions, type PlanResult, type PlanStep, type RagAuditInfo, type RagQueryResponse, type RagSource, type RagUploadResponse, type ReasoningOptions, type ReasoningResult, type RequestOptions, type RetrievalResult, ServerError, type SourceType, type StateTransition, type Task, type TaskClaim, type TaskStatus, type TaskVerification, TimeoutError, type ToolContent, type ToolDefinition, ToolNotFoundError, type UpdateAgentPatch, ValidationError, type Verdict, WauldoError, chatContent, guardIsBlocked, guardIsSafe, isTerminalStatus };
|
package/dist/index.d.ts
CHANGED
|
@@ -644,4 +644,175 @@ declare class ToolNotFoundError extends WauldoError {
|
|
|
644
644
|
constructor(toolName: string);
|
|
645
645
|
}
|
|
646
646
|
|
|
647
|
-
|
|
647
|
+
interface AgentsClientConfig {
|
|
648
|
+
baseUrl: string;
|
|
649
|
+
apiKey?: string;
|
|
650
|
+
/** Tenant identifier forwarded via x-rapidapi-user header. */
|
|
651
|
+
tenant?: string;
|
|
652
|
+
/** Per-request timeout in ms. Default 120_000. */
|
|
653
|
+
timeoutMs?: number;
|
|
654
|
+
}
|
|
655
|
+
interface DeployedAgent {
|
|
656
|
+
id: string;
|
|
657
|
+
tenant_id: string;
|
|
658
|
+
name: string;
|
|
659
|
+
description: string;
|
|
660
|
+
wauldo_toml: string;
|
|
661
|
+
agents_md?: string;
|
|
662
|
+
mcp_json?: string;
|
|
663
|
+
model_provider: string;
|
|
664
|
+
model_name: string;
|
|
665
|
+
preset?: string;
|
|
666
|
+
created_at: number;
|
|
667
|
+
updated_at: number;
|
|
668
|
+
}
|
|
669
|
+
interface CreateAgentInput {
|
|
670
|
+
name: string;
|
|
671
|
+
wauldoToml: string;
|
|
672
|
+
description?: string;
|
|
673
|
+
agentsMd?: string;
|
|
674
|
+
mcpJson?: string;
|
|
675
|
+
preset?: string;
|
|
676
|
+
}
|
|
677
|
+
interface UpdateAgentPatch {
|
|
678
|
+
description?: string;
|
|
679
|
+
wauldoToml?: string;
|
|
680
|
+
agentsMd?: string;
|
|
681
|
+
mcpJson?: string;
|
|
682
|
+
preset?: string;
|
|
683
|
+
}
|
|
684
|
+
interface AgentListResponse {
|
|
685
|
+
agents: DeployedAgent[];
|
|
686
|
+
pagination: {
|
|
687
|
+
total: number;
|
|
688
|
+
limit: number;
|
|
689
|
+
offset: number;
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
interface AgentRunResponse {
|
|
693
|
+
task_id: string;
|
|
694
|
+
agent_id: string;
|
|
695
|
+
status: string;
|
|
696
|
+
created_at: number;
|
|
697
|
+
}
|
|
698
|
+
interface A2aResponse {
|
|
699
|
+
task_id: string;
|
|
700
|
+
agent_id: string;
|
|
701
|
+
trace: string[];
|
|
702
|
+
depth: number;
|
|
703
|
+
status: string;
|
|
704
|
+
}
|
|
705
|
+
/** Verification verdict returned on completed tasks. */
|
|
706
|
+
type Verdict = "SAFE" | "UNCERTAIN" | "PARTIAL" | "BLOCK" | "CONFLICT" | "UNVERIFIED";
|
|
707
|
+
/** Task lifecycle status. */
|
|
708
|
+
type TaskStatus = "queued" | "running" | "completed" | "failed" | "cancelled";
|
|
709
|
+
/** A single verified claim from an agent output. */
|
|
710
|
+
interface TaskClaim {
|
|
711
|
+
text: string;
|
|
712
|
+
supported: boolean;
|
|
713
|
+
confidence: number;
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* Verification block attached to completed tasks. When
|
|
717
|
+
* `verification_source === "prompt_only"` the `confidence` and
|
|
718
|
+
* `hallucination_rate` fields reflect self-consistency only; rely on
|
|
719
|
+
* `verdict` + `trust_score` + `message` as authoritative.
|
|
720
|
+
*/
|
|
721
|
+
interface TaskVerification {
|
|
722
|
+
verdict: Verdict;
|
|
723
|
+
hallucination_rate: number;
|
|
724
|
+
confidence: number;
|
|
725
|
+
trust_score: number;
|
|
726
|
+
verification_source: string;
|
|
727
|
+
claims: TaskClaim[];
|
|
728
|
+
verification_retries: number;
|
|
729
|
+
/** Human-readable context for non-SAFE verdicts. */
|
|
730
|
+
message?: string | null;
|
|
731
|
+
sources_cited?: number[];
|
|
732
|
+
stripped_claims?: string[];
|
|
733
|
+
}
|
|
734
|
+
/** Full task record returned by `GET /v1/tasks/:id`. */
|
|
735
|
+
interface Task {
|
|
736
|
+
task_id: string;
|
|
737
|
+
tenant_id: string;
|
|
738
|
+
status: TaskStatus;
|
|
739
|
+
prompt: string;
|
|
740
|
+
created_at: number;
|
|
741
|
+
updated_at: number;
|
|
742
|
+
preset?: string | null;
|
|
743
|
+
result?: string | null;
|
|
744
|
+
error?: string | null;
|
|
745
|
+
partial_result?: string | null;
|
|
746
|
+
verification?: TaskVerification | null;
|
|
747
|
+
journal?: Record<string, unknown> | null;
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Single event yielded by `GET /v1/tasks/:id/stream`. Each SSE `data:`
|
|
751
|
+
* line is a JSON-serialised StateTransition emitted when a workflow
|
|
752
|
+
* state completes.
|
|
753
|
+
*/
|
|
754
|
+
interface StateTransition {
|
|
755
|
+
state_name: string;
|
|
756
|
+
to_state?: string | null;
|
|
757
|
+
condition: string;
|
|
758
|
+
raw_output: string;
|
|
759
|
+
validation_notes: string[];
|
|
760
|
+
timestamp: number;
|
|
761
|
+
success: boolean;
|
|
762
|
+
retry_count: number;
|
|
763
|
+
duration_ms: number;
|
|
764
|
+
prompt_tokens: number;
|
|
765
|
+
completion_tokens: number;
|
|
766
|
+
repair_count: number;
|
|
767
|
+
cache_hit: boolean;
|
|
768
|
+
}
|
|
769
|
+
declare function isTerminalStatus(s: TaskStatus | string): boolean;
|
|
770
|
+
declare class HttpError extends Error {
|
|
771
|
+
status: number;
|
|
772
|
+
statusText: string;
|
|
773
|
+
body: string;
|
|
774
|
+
constructor(status: number, statusText: string, body: string);
|
|
775
|
+
}
|
|
776
|
+
declare class AgentsClient {
|
|
777
|
+
private readonly config;
|
|
778
|
+
constructor(config: AgentsClientConfig);
|
|
779
|
+
private headers;
|
|
780
|
+
private request;
|
|
781
|
+
create(input: CreateAgentInput): Promise<DeployedAgent>;
|
|
782
|
+
list(limit?: number, offset?: number): Promise<AgentListResponse>;
|
|
783
|
+
get(agentId: string): Promise<DeployedAgent>;
|
|
784
|
+
update(agentId: string, patch: UpdateAgentPatch): Promise<DeployedAgent>;
|
|
785
|
+
delete(agentId: string): Promise<void>;
|
|
786
|
+
run(agentId: string, input: string, verificationMode?: "strict" | "balanced" | "permissive"): Promise<AgentRunResponse>;
|
|
787
|
+
a2aInvoke(agentId: string, input: string, trace?: string[], verificationMode?: "strict" | "balanced" | "permissive"): Promise<A2aResponse>;
|
|
788
|
+
/** `GET /v1/tasks/:id` — fetch the current state of a task. */
|
|
789
|
+
getTask(taskId: string): Promise<Task>;
|
|
790
|
+
/** `DELETE /v1/tasks/:id` — cancel a queued or running task. */
|
|
791
|
+
cancelTask(taskId: string): Promise<void>;
|
|
792
|
+
/**
|
|
793
|
+
* Poll `getTask` until the task reaches a terminal status. Resolves
|
|
794
|
+
* with the final Task snapshot. Rejects with `Error("timeout")` if
|
|
795
|
+
* the task is still running after `timeoutMs`. Use `streamTask` when
|
|
796
|
+
* you need event-by-event progress instead of a single final state.
|
|
797
|
+
*/
|
|
798
|
+
waitForTask(taskId: string, opts?: {
|
|
799
|
+
timeoutMs?: number;
|
|
800
|
+
pollIntervalMs?: number;
|
|
801
|
+
}): Promise<Task>;
|
|
802
|
+
/**
|
|
803
|
+
* Subscribe to `GET /v1/tasks/:id/stream` and yield typed
|
|
804
|
+
* StateTransition events as each workflow state completes. The
|
|
805
|
+
* generator closes when the upstream stream closes (task reached
|
|
806
|
+
* terminal status) or on connection error.
|
|
807
|
+
*
|
|
808
|
+
* @example
|
|
809
|
+
* ```ts
|
|
810
|
+
* for await (const event of agents.streamTask(run.task_id)) {
|
|
811
|
+
* console.log(event.state_name, event.duration_ms);
|
|
812
|
+
* }
|
|
813
|
+
* ```
|
|
814
|
+
*/
|
|
815
|
+
streamTask(taskId: string): AsyncGenerator<StateTransition>;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
export { type A2aResponse, AgentClient, type AgentListResponse, type AgentRunResponse, AgentsClient, type AgentsClientConfig, type CallToolResponse, type ChatChoice, type ChatClientLike, type ChatMessage, type ChatRequest, type ChatResponse, type ChatUsage, type Chunk, type ChunkResult, type ClientOptions, type Concept, type ConceptResult, ConnectionError, Conversation, type CreateAgentInput, type DeployedAgent, type DetailLevel, type EmbeddingData, type EmbeddingResponse, type EmbeddingUsage, type GraphNode, type GuardClaim, type GuardMode, type GuardResponse, HttpClient, type HttpClientConfig, HttpError, type KnowledgeGraphResult, type LogLevel, MockHttpClient, type ModelInfo, type ModelList, type OrchestratorResponse, type PlanOptions, type PlanResult, type PlanStep, type RagAuditInfo, type RagQueryResponse, type RagSource, type RagUploadResponse, type ReasoningOptions, type ReasoningResult, type RequestOptions, type RetrievalResult, ServerError, type SourceType, type StateTransition, type Task, type TaskClaim, type TaskStatus, type TaskVerification, TimeoutError, type ToolContent, type ToolDefinition, ToolNotFoundError, type UpdateAgentPatch, ValidationError, type Verdict, WauldoError, chatContent, guardIsBlocked, guardIsSafe, isTerminalStatus };
|
package/dist/index.js
CHANGED
|
@@ -21,9 +21,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
AgentClient: () => AgentClient,
|
|
24
|
+
AgentsClient: () => AgentsClient,
|
|
24
25
|
ConnectionError: () => ConnectionError,
|
|
25
26
|
Conversation: () => Conversation,
|
|
26
27
|
HttpClient: () => HttpClient,
|
|
28
|
+
HttpError: () => HttpError,
|
|
27
29
|
MockHttpClient: () => MockHttpClient,
|
|
28
30
|
ServerError: () => ServerError,
|
|
29
31
|
TimeoutError: () => TimeoutError,
|
|
@@ -32,7 +34,8 @@ __export(index_exports, {
|
|
|
32
34
|
WauldoError: () => WauldoError,
|
|
33
35
|
chatContent: () => chatContent,
|
|
34
36
|
guardIsBlocked: () => guardIsBlocked,
|
|
35
|
-
guardIsSafe: () => guardIsSafe
|
|
37
|
+
guardIsSafe: () => guardIsSafe,
|
|
38
|
+
isTerminalStatus: () => isTerminalStatus
|
|
36
39
|
});
|
|
37
40
|
module.exports = __toCommonJS(index_exports);
|
|
38
41
|
|
|
@@ -1284,12 +1287,239 @@ function guardIsSafe(response) {
|
|
|
1284
1287
|
function guardIsBlocked(response) {
|
|
1285
1288
|
return response.action === "block";
|
|
1286
1289
|
}
|
|
1290
|
+
|
|
1291
|
+
// src/agents.ts
|
|
1292
|
+
var MAX_RESPONSE_SIZE = 10 * 1024 * 1024;
|
|
1293
|
+
function isTerminalStatus(s) {
|
|
1294
|
+
return s === "completed" || s === "failed" || s === "cancelled";
|
|
1295
|
+
}
|
|
1296
|
+
async function _boundedRead(resp, limit = MAX_RESPONSE_SIZE) {
|
|
1297
|
+
if (!resp.body) return new Uint8Array(0);
|
|
1298
|
+
const reader = resp.body.getReader();
|
|
1299
|
+
const chunks = [];
|
|
1300
|
+
let total = 0;
|
|
1301
|
+
while (true) {
|
|
1302
|
+
const { done, value } = await reader.read();
|
|
1303
|
+
if (done) break;
|
|
1304
|
+
if (value) {
|
|
1305
|
+
total += value.byteLength;
|
|
1306
|
+
if (total > limit) {
|
|
1307
|
+
try {
|
|
1308
|
+
await reader.cancel();
|
|
1309
|
+
} catch {
|
|
1310
|
+
}
|
|
1311
|
+
throw new Error(
|
|
1312
|
+
`response body too large: >${limit} bytes`
|
|
1313
|
+
);
|
|
1314
|
+
}
|
|
1315
|
+
chunks.push(value);
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
const merged = new Uint8Array(total);
|
|
1319
|
+
let offset = 0;
|
|
1320
|
+
for (const c of chunks) {
|
|
1321
|
+
merged.set(c, offset);
|
|
1322
|
+
offset += c.byteLength;
|
|
1323
|
+
}
|
|
1324
|
+
return merged;
|
|
1325
|
+
}
|
|
1326
|
+
var HttpError = class extends Error {
|
|
1327
|
+
constructor(status, statusText, body) {
|
|
1328
|
+
super(`HTTP ${status} ${statusText}: ${body}`);
|
|
1329
|
+
this.status = status;
|
|
1330
|
+
this.statusText = statusText;
|
|
1331
|
+
this.body = body;
|
|
1332
|
+
this.name = "HttpError";
|
|
1333
|
+
}
|
|
1334
|
+
};
|
|
1335
|
+
var AgentsClient = class {
|
|
1336
|
+
constructor(config) {
|
|
1337
|
+
this.config = config;
|
|
1338
|
+
if (!config.baseUrl) throw new Error("baseUrl is required");
|
|
1339
|
+
}
|
|
1340
|
+
headers(extra) {
|
|
1341
|
+
const h = { "Content-Type": "application/json" };
|
|
1342
|
+
if (this.config.apiKey) h["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
1343
|
+
if (this.config.tenant) h["x-rapidapi-user"] = this.config.tenant;
|
|
1344
|
+
return { ...h, ...extra ?? {} };
|
|
1345
|
+
}
|
|
1346
|
+
async request(method, path, body, headerOverride) {
|
|
1347
|
+
const url = this.config.baseUrl.replace(/\/$/, "") + path;
|
|
1348
|
+
const controller = new AbortController();
|
|
1349
|
+
const timeout = setTimeout(
|
|
1350
|
+
() => controller.abort(),
|
|
1351
|
+
this.config.timeoutMs ?? 12e4
|
|
1352
|
+
);
|
|
1353
|
+
try {
|
|
1354
|
+
const init = {
|
|
1355
|
+
method,
|
|
1356
|
+
headers: this.headers(headerOverride),
|
|
1357
|
+
signal: controller.signal
|
|
1358
|
+
};
|
|
1359
|
+
if (body !== void 0) init.body = JSON.stringify(body);
|
|
1360
|
+
const resp = await fetch(url, init);
|
|
1361
|
+
if (resp.status === 204) return null;
|
|
1362
|
+
const bytes = await _boundedRead(resp);
|
|
1363
|
+
const text = new TextDecoder().decode(bytes);
|
|
1364
|
+
if (!resp.ok) {
|
|
1365
|
+
throw new HttpError(resp.status, resp.statusText, text);
|
|
1366
|
+
}
|
|
1367
|
+
return text ? JSON.parse(text) : null;
|
|
1368
|
+
} finally {
|
|
1369
|
+
clearTimeout(timeout);
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
// ── CRUD ────────────────────────────────────────────────────────
|
|
1373
|
+
async create(input) {
|
|
1374
|
+
const body = {
|
|
1375
|
+
name: input.name,
|
|
1376
|
+
wauldo_toml: input.wauldoToml,
|
|
1377
|
+
description: input.description ?? ""
|
|
1378
|
+
};
|
|
1379
|
+
if (input.agentsMd !== void 0) body.agents_md = input.agentsMd;
|
|
1380
|
+
if (input.mcpJson !== void 0) body.mcp_json = input.mcpJson;
|
|
1381
|
+
if (input.preset !== void 0) body.preset = input.preset;
|
|
1382
|
+
return await this.request("POST", "/v1/agents", body);
|
|
1383
|
+
}
|
|
1384
|
+
async list(limit = 20, offset = 0) {
|
|
1385
|
+
return await this.request(
|
|
1386
|
+
"GET",
|
|
1387
|
+
`/v1/agents?limit=${limit}&offset=${offset}`
|
|
1388
|
+
);
|
|
1389
|
+
}
|
|
1390
|
+
async get(agentId) {
|
|
1391
|
+
return await this.request("GET", `/v1/agents/${agentId}`);
|
|
1392
|
+
}
|
|
1393
|
+
async update(agentId, patch) {
|
|
1394
|
+
const body = {};
|
|
1395
|
+
if (patch.description !== void 0) body.description = patch.description;
|
|
1396
|
+
if (patch.wauldoToml !== void 0) body.wauldo_toml = patch.wauldoToml;
|
|
1397
|
+
if (patch.agentsMd !== void 0) body.agents_md = patch.agentsMd;
|
|
1398
|
+
if (patch.mcpJson !== void 0) body.mcp_json = patch.mcpJson;
|
|
1399
|
+
if (patch.preset !== void 0) body.preset = patch.preset;
|
|
1400
|
+
return await this.request("PATCH", `/v1/agents/${agentId}`, body);
|
|
1401
|
+
}
|
|
1402
|
+
async delete(agentId) {
|
|
1403
|
+
await this.request("DELETE", `/v1/agents/${agentId}`);
|
|
1404
|
+
}
|
|
1405
|
+
// ── Runs ────────────────────────────────────────────────────────
|
|
1406
|
+
async run(agentId, input, verificationMode) {
|
|
1407
|
+
if (!input) throw new Error("input is required");
|
|
1408
|
+
const body = { input };
|
|
1409
|
+
if (verificationMode) body.verification_mode = verificationMode;
|
|
1410
|
+
return await this.request(
|
|
1411
|
+
"POST",
|
|
1412
|
+
`/v1/agents/${agentId}/runs`,
|
|
1413
|
+
body
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1416
|
+
async a2aInvoke(agentId, input, trace, verificationMode) {
|
|
1417
|
+
if (!input) throw new Error("input is required");
|
|
1418
|
+
const body = { input };
|
|
1419
|
+
if (verificationMode) body.verification_mode = verificationMode;
|
|
1420
|
+
const extraHeaders = {};
|
|
1421
|
+
if (trace && trace.length > 0) extraHeaders["x-a2a-trace"] = trace.join(",");
|
|
1422
|
+
return await this.request(
|
|
1423
|
+
"POST",
|
|
1424
|
+
`/v1/a2a/${agentId}`,
|
|
1425
|
+
body,
|
|
1426
|
+
extraHeaders
|
|
1427
|
+
);
|
|
1428
|
+
}
|
|
1429
|
+
// ── Tasks (poll + stream) ───────────────────────────────────────
|
|
1430
|
+
/** `GET /v1/tasks/:id` — fetch the current state of a task. */
|
|
1431
|
+
async getTask(taskId) {
|
|
1432
|
+
return await this.request("GET", `/v1/tasks/${taskId}`);
|
|
1433
|
+
}
|
|
1434
|
+
/** `DELETE /v1/tasks/:id` — cancel a queued or running task. */
|
|
1435
|
+
async cancelTask(taskId) {
|
|
1436
|
+
await this.request("DELETE", `/v1/tasks/${taskId}`);
|
|
1437
|
+
}
|
|
1438
|
+
/**
|
|
1439
|
+
* Poll `getTask` until the task reaches a terminal status. Resolves
|
|
1440
|
+
* with the final Task snapshot. Rejects with `Error("timeout")` if
|
|
1441
|
+
* the task is still running after `timeoutMs`. Use `streamTask` when
|
|
1442
|
+
* you need event-by-event progress instead of a single final state.
|
|
1443
|
+
*/
|
|
1444
|
+
async waitForTask(taskId, opts = {}) {
|
|
1445
|
+
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
1446
|
+
const pollIntervalMs = opts.pollIntervalMs ?? 2e3;
|
|
1447
|
+
const deadline = Date.now() + timeoutMs;
|
|
1448
|
+
while (true) {
|
|
1449
|
+
const task = await this.getTask(taskId);
|
|
1450
|
+
if (isTerminalStatus(task.status)) return task;
|
|
1451
|
+
if (Date.now() >= deadline) {
|
|
1452
|
+
throw new Error(
|
|
1453
|
+
`task ${taskId} still in status '${task.status}' after ${timeoutMs}ms`
|
|
1454
|
+
);
|
|
1455
|
+
}
|
|
1456
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
/**
|
|
1460
|
+
* Subscribe to `GET /v1/tasks/:id/stream` and yield typed
|
|
1461
|
+
* StateTransition events as each workflow state completes. The
|
|
1462
|
+
* generator closes when the upstream stream closes (task reached
|
|
1463
|
+
* terminal status) or on connection error.
|
|
1464
|
+
*
|
|
1465
|
+
* @example
|
|
1466
|
+
* ```ts
|
|
1467
|
+
* for await (const event of agents.streamTask(run.task_id)) {
|
|
1468
|
+
* console.log(event.state_name, event.duration_ms);
|
|
1469
|
+
* }
|
|
1470
|
+
* ```
|
|
1471
|
+
*/
|
|
1472
|
+
async *streamTask(taskId) {
|
|
1473
|
+
const url = this.config.baseUrl.replace(/\/$/, "") + `/v1/tasks/${taskId}/stream`;
|
|
1474
|
+
const controller = new AbortController();
|
|
1475
|
+
const resp = await fetch(url, {
|
|
1476
|
+
method: "GET",
|
|
1477
|
+
headers: this.headers({ Accept: "text/event-stream" }),
|
|
1478
|
+
signal: controller.signal
|
|
1479
|
+
});
|
|
1480
|
+
if (!resp.ok) {
|
|
1481
|
+
const text = await resp.text().catch(() => "");
|
|
1482
|
+
throw new HttpError(resp.status, resp.statusText, text);
|
|
1483
|
+
}
|
|
1484
|
+
if (!resp.body) return;
|
|
1485
|
+
const reader = resp.body.getReader();
|
|
1486
|
+
const decoder = new TextDecoder();
|
|
1487
|
+
let buffer = "";
|
|
1488
|
+
try {
|
|
1489
|
+
while (true) {
|
|
1490
|
+
const { value, done } = await reader.read();
|
|
1491
|
+
if (done) break;
|
|
1492
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1493
|
+
const lines = buffer.split("\n");
|
|
1494
|
+
buffer = lines.pop() ?? "";
|
|
1495
|
+
for (const line of lines) {
|
|
1496
|
+
const trimmed = line.trimEnd().replace(/\r$/, "");
|
|
1497
|
+
if (!trimmed.startsWith("data:")) continue;
|
|
1498
|
+
const payload = trimmed.slice(5).trim();
|
|
1499
|
+
if (!payload) continue;
|
|
1500
|
+
try {
|
|
1501
|
+
const obj = JSON.parse(payload);
|
|
1502
|
+
yield obj;
|
|
1503
|
+
} catch {
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
} finally {
|
|
1508
|
+
try {
|
|
1509
|
+
controller.abort();
|
|
1510
|
+
} catch {
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
};
|
|
1287
1515
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1288
1516
|
0 && (module.exports = {
|
|
1289
1517
|
AgentClient,
|
|
1518
|
+
AgentsClient,
|
|
1290
1519
|
ConnectionError,
|
|
1291
1520
|
Conversation,
|
|
1292
1521
|
HttpClient,
|
|
1522
|
+
HttpError,
|
|
1293
1523
|
MockHttpClient,
|
|
1294
1524
|
ServerError,
|
|
1295
1525
|
TimeoutError,
|
|
@@ -1298,5 +1528,6 @@ function guardIsBlocked(response) {
|
|
|
1298
1528
|
WauldoError,
|
|
1299
1529
|
chatContent,
|
|
1300
1530
|
guardIsBlocked,
|
|
1301
|
-
guardIsSafe
|
|
1531
|
+
guardIsSafe,
|
|
1532
|
+
isTerminalStatus
|
|
1302
1533
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1246,11 +1246,238 @@ function guardIsSafe(response) {
|
|
|
1246
1246
|
function guardIsBlocked(response) {
|
|
1247
1247
|
return response.action === "block";
|
|
1248
1248
|
}
|
|
1249
|
+
|
|
1250
|
+
// src/agents.ts
|
|
1251
|
+
var MAX_RESPONSE_SIZE = 10 * 1024 * 1024;
|
|
1252
|
+
function isTerminalStatus(s) {
|
|
1253
|
+
return s === "completed" || s === "failed" || s === "cancelled";
|
|
1254
|
+
}
|
|
1255
|
+
async function _boundedRead(resp, limit = MAX_RESPONSE_SIZE) {
|
|
1256
|
+
if (!resp.body) return new Uint8Array(0);
|
|
1257
|
+
const reader = resp.body.getReader();
|
|
1258
|
+
const chunks = [];
|
|
1259
|
+
let total = 0;
|
|
1260
|
+
while (true) {
|
|
1261
|
+
const { done, value } = await reader.read();
|
|
1262
|
+
if (done) break;
|
|
1263
|
+
if (value) {
|
|
1264
|
+
total += value.byteLength;
|
|
1265
|
+
if (total > limit) {
|
|
1266
|
+
try {
|
|
1267
|
+
await reader.cancel();
|
|
1268
|
+
} catch {
|
|
1269
|
+
}
|
|
1270
|
+
throw new Error(
|
|
1271
|
+
`response body too large: >${limit} bytes`
|
|
1272
|
+
);
|
|
1273
|
+
}
|
|
1274
|
+
chunks.push(value);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
const merged = new Uint8Array(total);
|
|
1278
|
+
let offset = 0;
|
|
1279
|
+
for (const c of chunks) {
|
|
1280
|
+
merged.set(c, offset);
|
|
1281
|
+
offset += c.byteLength;
|
|
1282
|
+
}
|
|
1283
|
+
return merged;
|
|
1284
|
+
}
|
|
1285
|
+
var HttpError = class extends Error {
|
|
1286
|
+
constructor(status, statusText, body) {
|
|
1287
|
+
super(`HTTP ${status} ${statusText}: ${body}`);
|
|
1288
|
+
this.status = status;
|
|
1289
|
+
this.statusText = statusText;
|
|
1290
|
+
this.body = body;
|
|
1291
|
+
this.name = "HttpError";
|
|
1292
|
+
}
|
|
1293
|
+
};
|
|
1294
|
+
var AgentsClient = class {
|
|
1295
|
+
constructor(config) {
|
|
1296
|
+
this.config = config;
|
|
1297
|
+
if (!config.baseUrl) throw new Error("baseUrl is required");
|
|
1298
|
+
}
|
|
1299
|
+
headers(extra) {
|
|
1300
|
+
const h = { "Content-Type": "application/json" };
|
|
1301
|
+
if (this.config.apiKey) h["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
1302
|
+
if (this.config.tenant) h["x-rapidapi-user"] = this.config.tenant;
|
|
1303
|
+
return { ...h, ...extra ?? {} };
|
|
1304
|
+
}
|
|
1305
|
+
async request(method, path, body, headerOverride) {
|
|
1306
|
+
const url = this.config.baseUrl.replace(/\/$/, "") + path;
|
|
1307
|
+
const controller = new AbortController();
|
|
1308
|
+
const timeout = setTimeout(
|
|
1309
|
+
() => controller.abort(),
|
|
1310
|
+
this.config.timeoutMs ?? 12e4
|
|
1311
|
+
);
|
|
1312
|
+
try {
|
|
1313
|
+
const init = {
|
|
1314
|
+
method,
|
|
1315
|
+
headers: this.headers(headerOverride),
|
|
1316
|
+
signal: controller.signal
|
|
1317
|
+
};
|
|
1318
|
+
if (body !== void 0) init.body = JSON.stringify(body);
|
|
1319
|
+
const resp = await fetch(url, init);
|
|
1320
|
+
if (resp.status === 204) return null;
|
|
1321
|
+
const bytes = await _boundedRead(resp);
|
|
1322
|
+
const text = new TextDecoder().decode(bytes);
|
|
1323
|
+
if (!resp.ok) {
|
|
1324
|
+
throw new HttpError(resp.status, resp.statusText, text);
|
|
1325
|
+
}
|
|
1326
|
+
return text ? JSON.parse(text) : null;
|
|
1327
|
+
} finally {
|
|
1328
|
+
clearTimeout(timeout);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
// ── CRUD ────────────────────────────────────────────────────────
|
|
1332
|
+
async create(input) {
|
|
1333
|
+
const body = {
|
|
1334
|
+
name: input.name,
|
|
1335
|
+
wauldo_toml: input.wauldoToml,
|
|
1336
|
+
description: input.description ?? ""
|
|
1337
|
+
};
|
|
1338
|
+
if (input.agentsMd !== void 0) body.agents_md = input.agentsMd;
|
|
1339
|
+
if (input.mcpJson !== void 0) body.mcp_json = input.mcpJson;
|
|
1340
|
+
if (input.preset !== void 0) body.preset = input.preset;
|
|
1341
|
+
return await this.request("POST", "/v1/agents", body);
|
|
1342
|
+
}
|
|
1343
|
+
async list(limit = 20, offset = 0) {
|
|
1344
|
+
return await this.request(
|
|
1345
|
+
"GET",
|
|
1346
|
+
`/v1/agents?limit=${limit}&offset=${offset}`
|
|
1347
|
+
);
|
|
1348
|
+
}
|
|
1349
|
+
async get(agentId) {
|
|
1350
|
+
return await this.request("GET", `/v1/agents/${agentId}`);
|
|
1351
|
+
}
|
|
1352
|
+
async update(agentId, patch) {
|
|
1353
|
+
const body = {};
|
|
1354
|
+
if (patch.description !== void 0) body.description = patch.description;
|
|
1355
|
+
if (patch.wauldoToml !== void 0) body.wauldo_toml = patch.wauldoToml;
|
|
1356
|
+
if (patch.agentsMd !== void 0) body.agents_md = patch.agentsMd;
|
|
1357
|
+
if (patch.mcpJson !== void 0) body.mcp_json = patch.mcpJson;
|
|
1358
|
+
if (patch.preset !== void 0) body.preset = patch.preset;
|
|
1359
|
+
return await this.request("PATCH", `/v1/agents/${agentId}`, body);
|
|
1360
|
+
}
|
|
1361
|
+
async delete(agentId) {
|
|
1362
|
+
await this.request("DELETE", `/v1/agents/${agentId}`);
|
|
1363
|
+
}
|
|
1364
|
+
// ── Runs ────────────────────────────────────────────────────────
|
|
1365
|
+
async run(agentId, input, verificationMode) {
|
|
1366
|
+
if (!input) throw new Error("input is required");
|
|
1367
|
+
const body = { input };
|
|
1368
|
+
if (verificationMode) body.verification_mode = verificationMode;
|
|
1369
|
+
return await this.request(
|
|
1370
|
+
"POST",
|
|
1371
|
+
`/v1/agents/${agentId}/runs`,
|
|
1372
|
+
body
|
|
1373
|
+
);
|
|
1374
|
+
}
|
|
1375
|
+
async a2aInvoke(agentId, input, trace, verificationMode) {
|
|
1376
|
+
if (!input) throw new Error("input is required");
|
|
1377
|
+
const body = { input };
|
|
1378
|
+
if (verificationMode) body.verification_mode = verificationMode;
|
|
1379
|
+
const extraHeaders = {};
|
|
1380
|
+
if (trace && trace.length > 0) extraHeaders["x-a2a-trace"] = trace.join(",");
|
|
1381
|
+
return await this.request(
|
|
1382
|
+
"POST",
|
|
1383
|
+
`/v1/a2a/${agentId}`,
|
|
1384
|
+
body,
|
|
1385
|
+
extraHeaders
|
|
1386
|
+
);
|
|
1387
|
+
}
|
|
1388
|
+
// ── Tasks (poll + stream) ───────────────────────────────────────
|
|
1389
|
+
/** `GET /v1/tasks/:id` — fetch the current state of a task. */
|
|
1390
|
+
async getTask(taskId) {
|
|
1391
|
+
return await this.request("GET", `/v1/tasks/${taskId}`);
|
|
1392
|
+
}
|
|
1393
|
+
/** `DELETE /v1/tasks/:id` — cancel a queued or running task. */
|
|
1394
|
+
async cancelTask(taskId) {
|
|
1395
|
+
await this.request("DELETE", `/v1/tasks/${taskId}`);
|
|
1396
|
+
}
|
|
1397
|
+
/**
|
|
1398
|
+
* Poll `getTask` until the task reaches a terminal status. Resolves
|
|
1399
|
+
* with the final Task snapshot. Rejects with `Error("timeout")` if
|
|
1400
|
+
* the task is still running after `timeoutMs`. Use `streamTask` when
|
|
1401
|
+
* you need event-by-event progress instead of a single final state.
|
|
1402
|
+
*/
|
|
1403
|
+
async waitForTask(taskId, opts = {}) {
|
|
1404
|
+
const timeoutMs = opts.timeoutMs ?? 18e4;
|
|
1405
|
+
const pollIntervalMs = opts.pollIntervalMs ?? 2e3;
|
|
1406
|
+
const deadline = Date.now() + timeoutMs;
|
|
1407
|
+
while (true) {
|
|
1408
|
+
const task = await this.getTask(taskId);
|
|
1409
|
+
if (isTerminalStatus(task.status)) return task;
|
|
1410
|
+
if (Date.now() >= deadline) {
|
|
1411
|
+
throw new Error(
|
|
1412
|
+
`task ${taskId} still in status '${task.status}' after ${timeoutMs}ms`
|
|
1413
|
+
);
|
|
1414
|
+
}
|
|
1415
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* Subscribe to `GET /v1/tasks/:id/stream` and yield typed
|
|
1420
|
+
* StateTransition events as each workflow state completes. The
|
|
1421
|
+
* generator closes when the upstream stream closes (task reached
|
|
1422
|
+
* terminal status) or on connection error.
|
|
1423
|
+
*
|
|
1424
|
+
* @example
|
|
1425
|
+
* ```ts
|
|
1426
|
+
* for await (const event of agents.streamTask(run.task_id)) {
|
|
1427
|
+
* console.log(event.state_name, event.duration_ms);
|
|
1428
|
+
* }
|
|
1429
|
+
* ```
|
|
1430
|
+
*/
|
|
1431
|
+
async *streamTask(taskId) {
|
|
1432
|
+
const url = this.config.baseUrl.replace(/\/$/, "") + `/v1/tasks/${taskId}/stream`;
|
|
1433
|
+
const controller = new AbortController();
|
|
1434
|
+
const resp = await fetch(url, {
|
|
1435
|
+
method: "GET",
|
|
1436
|
+
headers: this.headers({ Accept: "text/event-stream" }),
|
|
1437
|
+
signal: controller.signal
|
|
1438
|
+
});
|
|
1439
|
+
if (!resp.ok) {
|
|
1440
|
+
const text = await resp.text().catch(() => "");
|
|
1441
|
+
throw new HttpError(resp.status, resp.statusText, text);
|
|
1442
|
+
}
|
|
1443
|
+
if (!resp.body) return;
|
|
1444
|
+
const reader = resp.body.getReader();
|
|
1445
|
+
const decoder = new TextDecoder();
|
|
1446
|
+
let buffer = "";
|
|
1447
|
+
try {
|
|
1448
|
+
while (true) {
|
|
1449
|
+
const { value, done } = await reader.read();
|
|
1450
|
+
if (done) break;
|
|
1451
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1452
|
+
const lines = buffer.split("\n");
|
|
1453
|
+
buffer = lines.pop() ?? "";
|
|
1454
|
+
for (const line of lines) {
|
|
1455
|
+
const trimmed = line.trimEnd().replace(/\r$/, "");
|
|
1456
|
+
if (!trimmed.startsWith("data:")) continue;
|
|
1457
|
+
const payload = trimmed.slice(5).trim();
|
|
1458
|
+
if (!payload) continue;
|
|
1459
|
+
try {
|
|
1460
|
+
const obj = JSON.parse(payload);
|
|
1461
|
+
yield obj;
|
|
1462
|
+
} catch {
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
} finally {
|
|
1467
|
+
try {
|
|
1468
|
+
controller.abort();
|
|
1469
|
+
} catch {
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1249
1474
|
export {
|
|
1250
1475
|
AgentClient,
|
|
1476
|
+
AgentsClient,
|
|
1251
1477
|
ConnectionError,
|
|
1252
1478
|
Conversation,
|
|
1253
1479
|
HttpClient,
|
|
1480
|
+
HttpError,
|
|
1254
1481
|
MockHttpClient,
|
|
1255
1482
|
ServerError,
|
|
1256
1483
|
TimeoutError,
|
|
@@ -1259,5 +1486,6 @@ export {
|
|
|
1259
1486
|
WauldoError,
|
|
1260
1487
|
chatContent,
|
|
1261
1488
|
guardIsBlocked,
|
|
1262
|
-
guardIsSafe
|
|
1489
|
+
guardIsSafe,
|
|
1490
|
+
isTerminalStatus
|
|
1263
1491
|
};
|