wauldo 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +109 -1
- package/dist/index.d.ts +109 -1
- package/dist/index.js +111 -0
- package/dist/index.mjs +110 -0
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -833,4 +833,112 @@ declare class AgentsClient {
|
|
|
833
833
|
streamTask(taskId: string): AsyncGenerator<StateTransition>;
|
|
834
834
|
}
|
|
835
835
|
|
|
836
|
-
|
|
836
|
+
/**
|
|
837
|
+
* History API client — Wauldo Funnel #1 audit log.
|
|
838
|
+
*
|
|
839
|
+
* Read-only access to a tenant's task history (every completed task is
|
|
840
|
+
* persisted to a tenant-scoped DynamoDB audit log on the server side,
|
|
841
|
+
* exposed via /v1/history). Mirrors {@link MemoryClient} shape so a
|
|
842
|
+
* caller already familiar with the Memory API has zero ramp-up.
|
|
843
|
+
*
|
|
844
|
+
* Three formats:
|
|
845
|
+
*
|
|
846
|
+
* - {@link HistoryClient.list} — paginated JSON, suitable for dashboards.
|
|
847
|
+
* - {@link HistoryClient.export} with `format="csv"` — single CSV blob
|
|
848
|
+
* (compliance evidence, header + footer metadata).
|
|
849
|
+
* - {@link HistoryClient.export} with `format="jsonl"` — newline-
|
|
850
|
+
* delimited JSON for log pipelines.
|
|
851
|
+
*
|
|
852
|
+
* Right To Be Forgotten (GDPR Art. 17) is supported via
|
|
853
|
+
* {@link HistoryClient.deleteTask}, which removes every audit row for a
|
|
854
|
+
* specific task id within the caller's tenant.
|
|
855
|
+
*
|
|
856
|
+
* @example
|
|
857
|
+
* ```ts
|
|
858
|
+
* import { HistoryClient } from "wauldo/history";
|
|
859
|
+
* const hist = new HistoryClient({
|
|
860
|
+
* baseUrl: "https://api.wauldo.com",
|
|
861
|
+
* apiKey: "tig_live_...",
|
|
862
|
+
* tenant: "my-org",
|
|
863
|
+
* });
|
|
864
|
+
* const page = await hist.list({ verdict: "CONFLICT", limit: 20 });
|
|
865
|
+
* for (const item of page.items) console.log(item.task_id, item.verdict);
|
|
866
|
+
* const blob = await hist.export({ format: "csv" });
|
|
867
|
+
* await hist.deleteTask("a69b8612-0c47-43f3-93f2-c00c8a4ac1f8");
|
|
868
|
+
* ```
|
|
869
|
+
*/
|
|
870
|
+
interface HistoryClientConfig {
|
|
871
|
+
baseUrl: string;
|
|
872
|
+
apiKey?: string;
|
|
873
|
+
tenant?: string;
|
|
874
|
+
timeoutMs?: number;
|
|
875
|
+
}
|
|
876
|
+
interface TaskHistoryEntry {
|
|
877
|
+
task_id: string;
|
|
878
|
+
tenant_id: string;
|
|
879
|
+
agent_id?: string | null;
|
|
880
|
+
verdict: string;
|
|
881
|
+
support_score: number;
|
|
882
|
+
halluc_rate: number;
|
|
883
|
+
latency_ms: number;
|
|
884
|
+
cost_micro_usd: number;
|
|
885
|
+
claims_count: number;
|
|
886
|
+
model?: string | null;
|
|
887
|
+
created_at: number;
|
|
888
|
+
}
|
|
889
|
+
interface HistoryListResponse {
|
|
890
|
+
items: TaskHistoryEntry[];
|
|
891
|
+
next_cursor: string | null;
|
|
892
|
+
/**
|
|
893
|
+
* `false` when the server hasn't wired its DynamoDB store (self-host
|
|
894
|
+
* without IAM perm). UI should show "audit log not enabled" rather
|
|
895
|
+
* than "no events yet" in that case.
|
|
896
|
+
*/
|
|
897
|
+
enabled: boolean;
|
|
898
|
+
}
|
|
899
|
+
interface ListOptions {
|
|
900
|
+
verdict?: string;
|
|
901
|
+
agentId?: string;
|
|
902
|
+
fromMs?: number;
|
|
903
|
+
toMs?: number;
|
|
904
|
+
limit?: number;
|
|
905
|
+
cursor?: string;
|
|
906
|
+
}
|
|
907
|
+
interface ExportOptions extends Omit<ListOptions, "limit" | "cursor"> {
|
|
908
|
+
format: "csv" | "jsonl" | "json";
|
|
909
|
+
}
|
|
910
|
+
declare class HistoryClient {
|
|
911
|
+
private readonly config;
|
|
912
|
+
constructor(config: HistoryClientConfig);
|
|
913
|
+
private headers;
|
|
914
|
+
private buildQs;
|
|
915
|
+
private fetchRaw;
|
|
916
|
+
/**
|
|
917
|
+
* GET /v1/history — paginated audit log page. Pass `cursor` from a
|
|
918
|
+
* previous response's `next_cursor` to paginate. Filters compose
|
|
919
|
+
* with AND.
|
|
920
|
+
*/
|
|
921
|
+
list(opts?: ListOptions): Promise<HistoryListResponse>;
|
|
922
|
+
/**
|
|
923
|
+
* Async generator over all pages within a window, yielding each page
|
|
924
|
+
* as the server returns it. Stops when `next_cursor` is null.
|
|
925
|
+
*/
|
|
926
|
+
iterPages(opts?: ListOptions): AsyncIterableIterator<HistoryListResponse>;
|
|
927
|
+
/**
|
|
928
|
+
* GET /v1/history?format=csv|jsonl — single-blob export. Returns
|
|
929
|
+
* the body as a string (`format=csv|jsonl`) or a parsed object
|
|
930
|
+
* (`format=json`). Server auto-paginates up to 10000 rows; the body
|
|
931
|
+
* footer (CSV `# wauldo-history-export ...` line / JSONL `_export`
|
|
932
|
+
* object) signals truncation. Rate-limited per tenant to 5 / 60s —
|
|
933
|
+
* a non-2xx response throws.
|
|
934
|
+
*/
|
|
935
|
+
export(opts: ExportOptions): Promise<string | HistoryListResponse>;
|
|
936
|
+
/**
|
|
937
|
+
* DELETE /v1/history/:task_id — RTBF (GDPR Art. 17). Removes every
|
|
938
|
+
* audit row for `taskId` within the caller's tenant. Idempotent.
|
|
939
|
+
* Returns the number of rows deleted.
|
|
940
|
+
*/
|
|
941
|
+
deleteTask(taskId: string): Promise<number>;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
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, HistoryClient, type HistoryClientConfig, type ExportOptions as HistoryExportOptions, type ListOptions as HistoryListOptions, type HistoryListResponse, 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 TaskHistoryEntry, type TaskStatus, type TaskVerification, TimeoutError, type ToolContent, type ToolDefinition, ToolNotFoundError, type UpdateAgentPatch, ValidationError, type Verdict, WauldoError, chatContent, guardIsBlocked, guardIsSafe, isTerminalStatus, supportScore };
|
package/dist/index.d.ts
CHANGED
|
@@ -833,4 +833,112 @@ declare class AgentsClient {
|
|
|
833
833
|
streamTask(taskId: string): AsyncGenerator<StateTransition>;
|
|
834
834
|
}
|
|
835
835
|
|
|
836
|
-
|
|
836
|
+
/**
|
|
837
|
+
* History API client — Wauldo Funnel #1 audit log.
|
|
838
|
+
*
|
|
839
|
+
* Read-only access to a tenant's task history (every completed task is
|
|
840
|
+
* persisted to a tenant-scoped DynamoDB audit log on the server side,
|
|
841
|
+
* exposed via /v1/history). Mirrors {@link MemoryClient} shape so a
|
|
842
|
+
* caller already familiar with the Memory API has zero ramp-up.
|
|
843
|
+
*
|
|
844
|
+
* Three formats:
|
|
845
|
+
*
|
|
846
|
+
* - {@link HistoryClient.list} — paginated JSON, suitable for dashboards.
|
|
847
|
+
* - {@link HistoryClient.export} with `format="csv"` — single CSV blob
|
|
848
|
+
* (compliance evidence, header + footer metadata).
|
|
849
|
+
* - {@link HistoryClient.export} with `format="jsonl"` — newline-
|
|
850
|
+
* delimited JSON for log pipelines.
|
|
851
|
+
*
|
|
852
|
+
* Right To Be Forgotten (GDPR Art. 17) is supported via
|
|
853
|
+
* {@link HistoryClient.deleteTask}, which removes every audit row for a
|
|
854
|
+
* specific task id within the caller's tenant.
|
|
855
|
+
*
|
|
856
|
+
* @example
|
|
857
|
+
* ```ts
|
|
858
|
+
* import { HistoryClient } from "wauldo/history";
|
|
859
|
+
* const hist = new HistoryClient({
|
|
860
|
+
* baseUrl: "https://api.wauldo.com",
|
|
861
|
+
* apiKey: "tig_live_...",
|
|
862
|
+
* tenant: "my-org",
|
|
863
|
+
* });
|
|
864
|
+
* const page = await hist.list({ verdict: "CONFLICT", limit: 20 });
|
|
865
|
+
* for (const item of page.items) console.log(item.task_id, item.verdict);
|
|
866
|
+
* const blob = await hist.export({ format: "csv" });
|
|
867
|
+
* await hist.deleteTask("a69b8612-0c47-43f3-93f2-c00c8a4ac1f8");
|
|
868
|
+
* ```
|
|
869
|
+
*/
|
|
870
|
+
interface HistoryClientConfig {
|
|
871
|
+
baseUrl: string;
|
|
872
|
+
apiKey?: string;
|
|
873
|
+
tenant?: string;
|
|
874
|
+
timeoutMs?: number;
|
|
875
|
+
}
|
|
876
|
+
interface TaskHistoryEntry {
|
|
877
|
+
task_id: string;
|
|
878
|
+
tenant_id: string;
|
|
879
|
+
agent_id?: string | null;
|
|
880
|
+
verdict: string;
|
|
881
|
+
support_score: number;
|
|
882
|
+
halluc_rate: number;
|
|
883
|
+
latency_ms: number;
|
|
884
|
+
cost_micro_usd: number;
|
|
885
|
+
claims_count: number;
|
|
886
|
+
model?: string | null;
|
|
887
|
+
created_at: number;
|
|
888
|
+
}
|
|
889
|
+
interface HistoryListResponse {
|
|
890
|
+
items: TaskHistoryEntry[];
|
|
891
|
+
next_cursor: string | null;
|
|
892
|
+
/**
|
|
893
|
+
* `false` when the server hasn't wired its DynamoDB store (self-host
|
|
894
|
+
* without IAM perm). UI should show "audit log not enabled" rather
|
|
895
|
+
* than "no events yet" in that case.
|
|
896
|
+
*/
|
|
897
|
+
enabled: boolean;
|
|
898
|
+
}
|
|
899
|
+
interface ListOptions {
|
|
900
|
+
verdict?: string;
|
|
901
|
+
agentId?: string;
|
|
902
|
+
fromMs?: number;
|
|
903
|
+
toMs?: number;
|
|
904
|
+
limit?: number;
|
|
905
|
+
cursor?: string;
|
|
906
|
+
}
|
|
907
|
+
interface ExportOptions extends Omit<ListOptions, "limit" | "cursor"> {
|
|
908
|
+
format: "csv" | "jsonl" | "json";
|
|
909
|
+
}
|
|
910
|
+
declare class HistoryClient {
|
|
911
|
+
private readonly config;
|
|
912
|
+
constructor(config: HistoryClientConfig);
|
|
913
|
+
private headers;
|
|
914
|
+
private buildQs;
|
|
915
|
+
private fetchRaw;
|
|
916
|
+
/**
|
|
917
|
+
* GET /v1/history — paginated audit log page. Pass `cursor` from a
|
|
918
|
+
* previous response's `next_cursor` to paginate. Filters compose
|
|
919
|
+
* with AND.
|
|
920
|
+
*/
|
|
921
|
+
list(opts?: ListOptions): Promise<HistoryListResponse>;
|
|
922
|
+
/**
|
|
923
|
+
* Async generator over all pages within a window, yielding each page
|
|
924
|
+
* as the server returns it. Stops when `next_cursor` is null.
|
|
925
|
+
*/
|
|
926
|
+
iterPages(opts?: ListOptions): AsyncIterableIterator<HistoryListResponse>;
|
|
927
|
+
/**
|
|
928
|
+
* GET /v1/history?format=csv|jsonl — single-blob export. Returns
|
|
929
|
+
* the body as a string (`format=csv|jsonl`) or a parsed object
|
|
930
|
+
* (`format=json`). Server auto-paginates up to 10000 rows; the body
|
|
931
|
+
* footer (CSV `# wauldo-history-export ...` line / JSONL `_export`
|
|
932
|
+
* object) signals truncation. Rate-limited per tenant to 5 / 60s —
|
|
933
|
+
* a non-2xx response throws.
|
|
934
|
+
*/
|
|
935
|
+
export(opts: ExportOptions): Promise<string | HistoryListResponse>;
|
|
936
|
+
/**
|
|
937
|
+
* DELETE /v1/history/:task_id — RTBF (GDPR Art. 17). Removes every
|
|
938
|
+
* audit row for `taskId` within the caller's tenant. Idempotent.
|
|
939
|
+
* Returns the number of rows deleted.
|
|
940
|
+
*/
|
|
941
|
+
deleteTask(taskId: string): Promise<number>;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
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, HistoryClient, type HistoryClientConfig, type ExportOptions as HistoryExportOptions, type ListOptions as HistoryListOptions, type HistoryListResponse, 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 TaskHistoryEntry, type TaskStatus, type TaskVerification, TimeoutError, type ToolContent, type ToolDefinition, ToolNotFoundError, type UpdateAgentPatch, ValidationError, type Verdict, WauldoError, chatContent, guardIsBlocked, guardIsSafe, isTerminalStatus, supportScore };
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ __export(index_exports, {
|
|
|
24
24
|
AgentsClient: () => AgentsClient,
|
|
25
25
|
ConnectionError: () => ConnectionError,
|
|
26
26
|
Conversation: () => Conversation,
|
|
27
|
+
HistoryClient: () => HistoryClient,
|
|
27
28
|
HttpClient: () => HttpClient,
|
|
28
29
|
HttpError: () => HttpError,
|
|
29
30
|
MockHttpClient: () => MockHttpClient,
|
|
@@ -1518,12 +1519,122 @@ var AgentsClient = class {
|
|
|
1518
1519
|
}
|
|
1519
1520
|
}
|
|
1520
1521
|
};
|
|
1522
|
+
|
|
1523
|
+
// src/history.ts
|
|
1524
|
+
var HistoryClient = class {
|
|
1525
|
+
constructor(config) {
|
|
1526
|
+
this.config = config;
|
|
1527
|
+
if (!config.baseUrl) throw new Error("baseUrl is required");
|
|
1528
|
+
}
|
|
1529
|
+
headers() {
|
|
1530
|
+
const h = { "Content-Type": "application/json" };
|
|
1531
|
+
if (this.config.apiKey) h["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
1532
|
+
if (this.config.tenant) h["x-rapidapi-user"] = this.config.tenant;
|
|
1533
|
+
return h;
|
|
1534
|
+
}
|
|
1535
|
+
buildQs(params) {
|
|
1536
|
+
const entries = Object.entries(params).filter(([, v]) => v !== void 0 && v !== null);
|
|
1537
|
+
if (entries.length === 0) return "";
|
|
1538
|
+
const usp = new URLSearchParams();
|
|
1539
|
+
for (const [k, v] of entries) usp.set(k, String(v));
|
|
1540
|
+
return "?" + usp.toString();
|
|
1541
|
+
}
|
|
1542
|
+
async fetchRaw(method, path) {
|
|
1543
|
+
const url = this.config.baseUrl.replace(/\/$/, "") + path;
|
|
1544
|
+
const controller = new AbortController();
|
|
1545
|
+
const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs ?? 6e4);
|
|
1546
|
+
try {
|
|
1547
|
+
const resp = await fetch(url, {
|
|
1548
|
+
method,
|
|
1549
|
+
headers: this.headers(),
|
|
1550
|
+
signal: controller.signal
|
|
1551
|
+
});
|
|
1552
|
+
if (!resp.ok) {
|
|
1553
|
+
const body = await resp.text().catch(() => "");
|
|
1554
|
+
throw new Error(`HTTP ${resp.status} ${resp.statusText}: ${body.slice(0, 200)}`);
|
|
1555
|
+
}
|
|
1556
|
+
return resp;
|
|
1557
|
+
} finally {
|
|
1558
|
+
clearTimeout(timeout);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
/**
|
|
1562
|
+
* GET /v1/history — paginated audit log page. Pass `cursor` from a
|
|
1563
|
+
* previous response's `next_cursor` to paginate. Filters compose
|
|
1564
|
+
* with AND.
|
|
1565
|
+
*/
|
|
1566
|
+
async list(opts = {}) {
|
|
1567
|
+
const qs = this.buildQs({
|
|
1568
|
+
verdict: opts.verdict,
|
|
1569
|
+
agent_id: opts.agentId,
|
|
1570
|
+
from: opts.fromMs,
|
|
1571
|
+
to: opts.toMs,
|
|
1572
|
+
limit: opts.limit,
|
|
1573
|
+
cursor: opts.cursor
|
|
1574
|
+
});
|
|
1575
|
+
const resp = await this.fetchRaw("GET", `/v1/history${qs}`);
|
|
1576
|
+
return await resp.json();
|
|
1577
|
+
}
|
|
1578
|
+
/**
|
|
1579
|
+
* Async generator over all pages within a window, yielding each page
|
|
1580
|
+
* as the server returns it. Stops when `next_cursor` is null.
|
|
1581
|
+
*/
|
|
1582
|
+
async *iterPages(opts = {}) {
|
|
1583
|
+
let cursor = opts.cursor;
|
|
1584
|
+
const pageSize = opts.limit ?? 50;
|
|
1585
|
+
while (true) {
|
|
1586
|
+
const next = { ...opts, limit: pageSize };
|
|
1587
|
+
if (cursor !== void 0) next.cursor = cursor;
|
|
1588
|
+
const page = await this.list(next);
|
|
1589
|
+
yield page;
|
|
1590
|
+
if (!page.next_cursor) break;
|
|
1591
|
+
cursor = page.next_cursor;
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
/**
|
|
1595
|
+
* GET /v1/history?format=csv|jsonl — single-blob export. Returns
|
|
1596
|
+
* the body as a string (`format=csv|jsonl`) or a parsed object
|
|
1597
|
+
* (`format=json`). Server auto-paginates up to 10000 rows; the body
|
|
1598
|
+
* footer (CSV `# wauldo-history-export ...` line / JSONL `_export`
|
|
1599
|
+
* object) signals truncation. Rate-limited per tenant to 5 / 60s —
|
|
1600
|
+
* a non-2xx response throws.
|
|
1601
|
+
*/
|
|
1602
|
+
async export(opts) {
|
|
1603
|
+
if (!["csv", "jsonl", "json"].includes(opts.format)) {
|
|
1604
|
+
throw new Error(`unsupported format '${opts.format}' \u2014 use csv|jsonl|json`);
|
|
1605
|
+
}
|
|
1606
|
+
const qs = this.buildQs({
|
|
1607
|
+
format: opts.format,
|
|
1608
|
+
verdict: opts.verdict,
|
|
1609
|
+
agent_id: opts.agentId,
|
|
1610
|
+
from: opts.fromMs,
|
|
1611
|
+
to: opts.toMs
|
|
1612
|
+
});
|
|
1613
|
+
const resp = await this.fetchRaw("GET", `/v1/history${qs}`);
|
|
1614
|
+
if (opts.format === "json") {
|
|
1615
|
+
return await resp.json();
|
|
1616
|
+
}
|
|
1617
|
+
return await resp.text();
|
|
1618
|
+
}
|
|
1619
|
+
/**
|
|
1620
|
+
* DELETE /v1/history/:task_id — RTBF (GDPR Art. 17). Removes every
|
|
1621
|
+
* audit row for `taskId` within the caller's tenant. Idempotent.
|
|
1622
|
+
* Returns the number of rows deleted.
|
|
1623
|
+
*/
|
|
1624
|
+
async deleteTask(taskId) {
|
|
1625
|
+
if (!taskId) throw new Error("taskId required");
|
|
1626
|
+
const resp = await this.fetchRaw("DELETE", `/v1/history/${encodeURIComponent(taskId)}`);
|
|
1627
|
+
const body = await resp.json();
|
|
1628
|
+
return Number(body?.deleted ?? 0);
|
|
1629
|
+
}
|
|
1630
|
+
};
|
|
1521
1631
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1522
1632
|
0 && (module.exports = {
|
|
1523
1633
|
AgentClient,
|
|
1524
1634
|
AgentsClient,
|
|
1525
1635
|
ConnectionError,
|
|
1526
1636
|
Conversation,
|
|
1637
|
+
HistoryClient,
|
|
1527
1638
|
HttpClient,
|
|
1528
1639
|
HttpError,
|
|
1529
1640
|
MockHttpClient,
|
package/dist/index.mjs
CHANGED
|
@@ -1476,11 +1476,121 @@ var AgentsClient = class {
|
|
|
1476
1476
|
}
|
|
1477
1477
|
}
|
|
1478
1478
|
};
|
|
1479
|
+
|
|
1480
|
+
// src/history.ts
|
|
1481
|
+
var HistoryClient = class {
|
|
1482
|
+
constructor(config) {
|
|
1483
|
+
this.config = config;
|
|
1484
|
+
if (!config.baseUrl) throw new Error("baseUrl is required");
|
|
1485
|
+
}
|
|
1486
|
+
headers() {
|
|
1487
|
+
const h = { "Content-Type": "application/json" };
|
|
1488
|
+
if (this.config.apiKey) h["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
1489
|
+
if (this.config.tenant) h["x-rapidapi-user"] = this.config.tenant;
|
|
1490
|
+
return h;
|
|
1491
|
+
}
|
|
1492
|
+
buildQs(params) {
|
|
1493
|
+
const entries = Object.entries(params).filter(([, v]) => v !== void 0 && v !== null);
|
|
1494
|
+
if (entries.length === 0) return "";
|
|
1495
|
+
const usp = new URLSearchParams();
|
|
1496
|
+
for (const [k, v] of entries) usp.set(k, String(v));
|
|
1497
|
+
return "?" + usp.toString();
|
|
1498
|
+
}
|
|
1499
|
+
async fetchRaw(method, path) {
|
|
1500
|
+
const url = this.config.baseUrl.replace(/\/$/, "") + path;
|
|
1501
|
+
const controller = new AbortController();
|
|
1502
|
+
const timeout = setTimeout(() => controller.abort(), this.config.timeoutMs ?? 6e4);
|
|
1503
|
+
try {
|
|
1504
|
+
const resp = await fetch(url, {
|
|
1505
|
+
method,
|
|
1506
|
+
headers: this.headers(),
|
|
1507
|
+
signal: controller.signal
|
|
1508
|
+
});
|
|
1509
|
+
if (!resp.ok) {
|
|
1510
|
+
const body = await resp.text().catch(() => "");
|
|
1511
|
+
throw new Error(`HTTP ${resp.status} ${resp.statusText}: ${body.slice(0, 200)}`);
|
|
1512
|
+
}
|
|
1513
|
+
return resp;
|
|
1514
|
+
} finally {
|
|
1515
|
+
clearTimeout(timeout);
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
/**
|
|
1519
|
+
* GET /v1/history — paginated audit log page. Pass `cursor` from a
|
|
1520
|
+
* previous response's `next_cursor` to paginate. Filters compose
|
|
1521
|
+
* with AND.
|
|
1522
|
+
*/
|
|
1523
|
+
async list(opts = {}) {
|
|
1524
|
+
const qs = this.buildQs({
|
|
1525
|
+
verdict: opts.verdict,
|
|
1526
|
+
agent_id: opts.agentId,
|
|
1527
|
+
from: opts.fromMs,
|
|
1528
|
+
to: opts.toMs,
|
|
1529
|
+
limit: opts.limit,
|
|
1530
|
+
cursor: opts.cursor
|
|
1531
|
+
});
|
|
1532
|
+
const resp = await this.fetchRaw("GET", `/v1/history${qs}`);
|
|
1533
|
+
return await resp.json();
|
|
1534
|
+
}
|
|
1535
|
+
/**
|
|
1536
|
+
* Async generator over all pages within a window, yielding each page
|
|
1537
|
+
* as the server returns it. Stops when `next_cursor` is null.
|
|
1538
|
+
*/
|
|
1539
|
+
async *iterPages(opts = {}) {
|
|
1540
|
+
let cursor = opts.cursor;
|
|
1541
|
+
const pageSize = opts.limit ?? 50;
|
|
1542
|
+
while (true) {
|
|
1543
|
+
const next = { ...opts, limit: pageSize };
|
|
1544
|
+
if (cursor !== void 0) next.cursor = cursor;
|
|
1545
|
+
const page = await this.list(next);
|
|
1546
|
+
yield page;
|
|
1547
|
+
if (!page.next_cursor) break;
|
|
1548
|
+
cursor = page.next_cursor;
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
/**
|
|
1552
|
+
* GET /v1/history?format=csv|jsonl — single-blob export. Returns
|
|
1553
|
+
* the body as a string (`format=csv|jsonl`) or a parsed object
|
|
1554
|
+
* (`format=json`). Server auto-paginates up to 10000 rows; the body
|
|
1555
|
+
* footer (CSV `# wauldo-history-export ...` line / JSONL `_export`
|
|
1556
|
+
* object) signals truncation. Rate-limited per tenant to 5 / 60s —
|
|
1557
|
+
* a non-2xx response throws.
|
|
1558
|
+
*/
|
|
1559
|
+
async export(opts) {
|
|
1560
|
+
if (!["csv", "jsonl", "json"].includes(opts.format)) {
|
|
1561
|
+
throw new Error(`unsupported format '${opts.format}' \u2014 use csv|jsonl|json`);
|
|
1562
|
+
}
|
|
1563
|
+
const qs = this.buildQs({
|
|
1564
|
+
format: opts.format,
|
|
1565
|
+
verdict: opts.verdict,
|
|
1566
|
+
agent_id: opts.agentId,
|
|
1567
|
+
from: opts.fromMs,
|
|
1568
|
+
to: opts.toMs
|
|
1569
|
+
});
|
|
1570
|
+
const resp = await this.fetchRaw("GET", `/v1/history${qs}`);
|
|
1571
|
+
if (opts.format === "json") {
|
|
1572
|
+
return await resp.json();
|
|
1573
|
+
}
|
|
1574
|
+
return await resp.text();
|
|
1575
|
+
}
|
|
1576
|
+
/**
|
|
1577
|
+
* DELETE /v1/history/:task_id — RTBF (GDPR Art. 17). Removes every
|
|
1578
|
+
* audit row for `taskId` within the caller's tenant. Idempotent.
|
|
1579
|
+
* Returns the number of rows deleted.
|
|
1580
|
+
*/
|
|
1581
|
+
async deleteTask(taskId) {
|
|
1582
|
+
if (!taskId) throw new Error("taskId required");
|
|
1583
|
+
const resp = await this.fetchRaw("DELETE", `/v1/history/${encodeURIComponent(taskId)}`);
|
|
1584
|
+
const body = await resp.json();
|
|
1585
|
+
return Number(body?.deleted ?? 0);
|
|
1586
|
+
}
|
|
1587
|
+
};
|
|
1479
1588
|
export {
|
|
1480
1589
|
AgentClient,
|
|
1481
1590
|
AgentsClient,
|
|
1482
1591
|
ConnectionError,
|
|
1483
1592
|
Conversation,
|
|
1593
|
+
HistoryClient,
|
|
1484
1594
|
HttpClient,
|
|
1485
1595
|
HttpError,
|
|
1486
1596
|
MockHttpClient,
|