wauldo 0.7.1 → 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 +173 -1
- package/dist/index.d.ts +173 -1
- package/dist/index.js +261 -2
- package/dist/index.mjs +257 -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
|
@@ -593,6 +593,7 @@ declare class MockHttpClient {
|
|
|
593
593
|
system?: string;
|
|
594
594
|
model?: string;
|
|
595
595
|
}): Conversation;
|
|
596
|
+
guard(text: string, sourceContext: string, mode?: GuardMode, _options?: RequestOptions): Promise<GuardResponse>;
|
|
596
597
|
ragAsk(question: string, text: string, source?: string): Promise<string>;
|
|
597
598
|
private record;
|
|
598
599
|
}
|
|
@@ -643,4 +644,175 @@ declare class ToolNotFoundError extends WauldoError {
|
|
|
643
644
|
constructor(toolName: string);
|
|
644
645
|
}
|
|
645
646
|
|
|
646
|
-
|
|
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
|
@@ -593,6 +593,7 @@ declare class MockHttpClient {
|
|
|
593
593
|
system?: string;
|
|
594
594
|
model?: string;
|
|
595
595
|
}): Conversation;
|
|
596
|
+
guard(text: string, sourceContext: string, mode?: GuardMode, _options?: RequestOptions): Promise<GuardResponse>;
|
|
596
597
|
ragAsk(question: string, text: string, source?: string): Promise<string>;
|
|
597
598
|
private record;
|
|
598
599
|
}
|
|
@@ -643,4 +644,175 @@ declare class ToolNotFoundError extends WauldoError {
|
|
|
643
644
|
constructor(toolName: string);
|
|
644
645
|
}
|
|
645
646
|
|
|
646
|
-
|
|
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
|
|
|
@@ -1235,6 +1238,34 @@ var MockHttpClient = class {
|
|
|
1235
1238
|
this.record("conversation", options);
|
|
1236
1239
|
return new Conversation(this, options);
|
|
1237
1240
|
}
|
|
1241
|
+
async guard(text, sourceContext, mode = "lexical", _options) {
|
|
1242
|
+
this.record("guard", text, sourceContext, mode);
|
|
1243
|
+
const textNums = new Set(text.match(/\b\d+(?:\.\d+)?\b/g) ?? []);
|
|
1244
|
+
const srcNums = new Set(sourceContext.match(/\b\d+(?:\.\d+)?\b/g) ?? []);
|
|
1245
|
+
const mismatch = textNums.size > 0 && srcNums.size > 0 && [...textNums].some((n) => !srcNums.has(n));
|
|
1246
|
+
if (mismatch) {
|
|
1247
|
+
return {
|
|
1248
|
+
verdict: "rejected",
|
|
1249
|
+
action: "block",
|
|
1250
|
+
hallucination_rate: 1,
|
|
1251
|
+
mode,
|
|
1252
|
+
total_claims: 1,
|
|
1253
|
+
supported_claims: 0,
|
|
1254
|
+
confidence: 0,
|
|
1255
|
+
claims: [{ text, supported: false, confidence: 0.3, verdict: "rejected", action: "block", reason: "numerical_mismatch" }]
|
|
1256
|
+
};
|
|
1257
|
+
}
|
|
1258
|
+
return {
|
|
1259
|
+
verdict: "verified",
|
|
1260
|
+
action: "allow",
|
|
1261
|
+
hallucination_rate: 0,
|
|
1262
|
+
mode,
|
|
1263
|
+
total_claims: 1,
|
|
1264
|
+
supported_claims: 1,
|
|
1265
|
+
confidence: 0.95,
|
|
1266
|
+
claims: [{ text, supported: true, confidence: 0.95, verdict: "verified", action: "allow" }]
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1238
1269
|
async ragAsk(question, text, source = "document") {
|
|
1239
1270
|
this.record("ragAsk", question, text, source);
|
|
1240
1271
|
await this.ragUpload(text, source);
|
|
@@ -1256,12 +1287,239 @@ function guardIsSafe(response) {
|
|
|
1256
1287
|
function guardIsBlocked(response) {
|
|
1257
1288
|
return response.action === "block";
|
|
1258
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
|
+
};
|
|
1259
1515
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1260
1516
|
0 && (module.exports = {
|
|
1261
1517
|
AgentClient,
|
|
1518
|
+
AgentsClient,
|
|
1262
1519
|
ConnectionError,
|
|
1263
1520
|
Conversation,
|
|
1264
1521
|
HttpClient,
|
|
1522
|
+
HttpError,
|
|
1265
1523
|
MockHttpClient,
|
|
1266
1524
|
ServerError,
|
|
1267
1525
|
TimeoutError,
|
|
@@ -1270,5 +1528,6 @@ function guardIsBlocked(response) {
|
|
|
1270
1528
|
WauldoError,
|
|
1271
1529
|
chatContent,
|
|
1272
1530
|
guardIsBlocked,
|
|
1273
|
-
guardIsSafe
|
|
1531
|
+
guardIsSafe,
|
|
1532
|
+
isTerminalStatus
|
|
1274
1533
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1197,6 +1197,34 @@ var MockHttpClient = class {
|
|
|
1197
1197
|
this.record("conversation", options);
|
|
1198
1198
|
return new Conversation(this, options);
|
|
1199
1199
|
}
|
|
1200
|
+
async guard(text, sourceContext, mode = "lexical", _options) {
|
|
1201
|
+
this.record("guard", text, sourceContext, mode);
|
|
1202
|
+
const textNums = new Set(text.match(/\b\d+(?:\.\d+)?\b/g) ?? []);
|
|
1203
|
+
const srcNums = new Set(sourceContext.match(/\b\d+(?:\.\d+)?\b/g) ?? []);
|
|
1204
|
+
const mismatch = textNums.size > 0 && srcNums.size > 0 && [...textNums].some((n) => !srcNums.has(n));
|
|
1205
|
+
if (mismatch) {
|
|
1206
|
+
return {
|
|
1207
|
+
verdict: "rejected",
|
|
1208
|
+
action: "block",
|
|
1209
|
+
hallucination_rate: 1,
|
|
1210
|
+
mode,
|
|
1211
|
+
total_claims: 1,
|
|
1212
|
+
supported_claims: 0,
|
|
1213
|
+
confidence: 0,
|
|
1214
|
+
claims: [{ text, supported: false, confidence: 0.3, verdict: "rejected", action: "block", reason: "numerical_mismatch" }]
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
return {
|
|
1218
|
+
verdict: "verified",
|
|
1219
|
+
action: "allow",
|
|
1220
|
+
hallucination_rate: 0,
|
|
1221
|
+
mode,
|
|
1222
|
+
total_claims: 1,
|
|
1223
|
+
supported_claims: 1,
|
|
1224
|
+
confidence: 0.95,
|
|
1225
|
+
claims: [{ text, supported: true, confidence: 0.95, verdict: "verified", action: "allow" }]
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1200
1228
|
async ragAsk(question, text, source = "document") {
|
|
1201
1229
|
this.record("ragAsk", question, text, source);
|
|
1202
1230
|
await this.ragUpload(text, source);
|
|
@@ -1218,11 +1246,238 @@ function guardIsSafe(response) {
|
|
|
1218
1246
|
function guardIsBlocked(response) {
|
|
1219
1247
|
return response.action === "block";
|
|
1220
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
|
+
};
|
|
1221
1474
|
export {
|
|
1222
1475
|
AgentClient,
|
|
1476
|
+
AgentsClient,
|
|
1223
1477
|
ConnectionError,
|
|
1224
1478
|
Conversation,
|
|
1225
1479
|
HttpClient,
|
|
1480
|
+
HttpError,
|
|
1226
1481
|
MockHttpClient,
|
|
1227
1482
|
ServerError,
|
|
1228
1483
|
TimeoutError,
|
|
@@ -1231,5 +1486,6 @@ export {
|
|
|
1231
1486
|
WauldoError,
|
|
1232
1487
|
chatContent,
|
|
1233
1488
|
guardIsBlocked,
|
|
1234
|
-
guardIsSafe
|
|
1489
|
+
guardIsSafe,
|
|
1490
|
+
isTerminalStatus
|
|
1235
1491
|
};
|