@agent-os-sdk/client 0.9.14 → 0.9.15

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.
Files changed (50) hide show
  1. package/dist/client/AgentOsClient.d.ts +8 -4
  2. package/dist/client/AgentOsClient.d.ts.map +1 -1
  3. package/dist/client/AgentOsClient.js +12 -6
  4. package/dist/errors/factory.d.ts +2 -0
  5. package/dist/errors/factory.d.ts.map +1 -1
  6. package/dist/errors/factory.js +5 -1
  7. package/dist/generated/openapi.d.ts +544 -744
  8. package/dist/generated/openapi.d.ts.map +1 -1
  9. package/dist/index.d.ts +8 -2
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +8 -2
  12. package/dist/modules/agents.d.ts +25 -7
  13. package/dist/modules/agents.d.ts.map +1 -1
  14. package/dist/modules/agents.js +36 -7
  15. package/dist/modules/contracts.d.ts +48 -0
  16. package/dist/modules/contracts.d.ts.map +1 -0
  17. package/dist/modules/contracts.js +25 -0
  18. package/dist/modules/evaluation.d.ts +64 -0
  19. package/dist/modules/evaluation.d.ts.map +1 -1
  20. package/dist/modules/evaluation.js +12 -0
  21. package/dist/modules/improvements.d.ts +52 -0
  22. package/dist/modules/improvements.d.ts.map +1 -0
  23. package/dist/modules/improvements.js +27 -0
  24. package/dist/modules/metaAgent.d.ts +62 -0
  25. package/dist/modules/metaAgent.d.ts.map +1 -0
  26. package/dist/modules/metaAgent.js +25 -0
  27. package/dist/modules/presets.d.ts.map +1 -1
  28. package/dist/modules/presets.js +113 -44
  29. package/dist/modules/runs.d.ts +9 -0
  30. package/dist/modules/runs.d.ts.map +1 -1
  31. package/dist/modules/runs.js +14 -1
  32. package/dist/modules/templates.d.ts +28 -0
  33. package/dist/modules/templates.d.ts.map +1 -0
  34. package/dist/modules/templates.js +19 -0
  35. package/package.json +2 -2
  36. package/src/client/AgentOsClient.ts +12 -6
  37. package/src/errors/factory.ts +7 -2
  38. package/src/generated/openapi.ts +544 -744
  39. package/src/generated/swagger.json +551 -924
  40. package/src/index.ts +22 -2
  41. package/src/modules/agents.ts +62 -8
  42. package/src/modules/contracts.ts +80 -0
  43. package/src/modules/evaluation.ts +80 -0
  44. package/src/modules/improvements.ts +71 -0
  45. package/src/modules/metaAgent.ts +87 -0
  46. package/src/modules/presets.ts +118 -50
  47. package/src/modules/runs.ts +20 -1
  48. package/src/modules/templates.ts +40 -0
  49. package/src/modules/builder.ts +0 -456
  50. package/src/modules/graphs.ts +0 -188
package/src/index.ts CHANGED
@@ -17,7 +17,7 @@
17
17
  * import { createClient } from "@agent-os-sdk/client";
18
18
  *
19
19
  * const api = createClient({ baseUrl, headers });
20
- * const { data } = await api.POST("/v1/api/graph/commit", { body: {...} });
20
+ * const { data } = await api.POST("/v1/api/contracts/validate", { body: {...} });
21
21
  * ```
22
22
  *
23
23
  * @example Custom Client (ergonomic wrapper)
@@ -25,7 +25,7 @@
25
25
  * import { AgentOsClient } from "@agent-os-sdk/client";
26
26
  *
27
27
  * const client = new AgentOsClient({ baseUrl, auth: {...} });
28
- * const { data } = await client.graphs.commit({...});
28
+ * const { data } = await client.contracts.validate({...});
29
29
  * ```
30
30
  */
31
31
 
@@ -97,15 +97,35 @@ export type { SSEEvent, SSEOptions } from "./sse/client.js";
97
97
  export * from "./modules/agents.js";
98
98
  export * from "./modules/auth.js";
99
99
  export * from "./modules/chatwoot.js";
100
+ export * from "./modules/catalog.js";
101
+ export * from "./modules/contracts.js";
100
102
  export * from "./modules/credentials.js";
101
103
  export * from "./modules/datasets.js";
104
+ export {
105
+ EvaluationModule,
106
+ type EvalDataset,
107
+ type DatasetListResponse,
108
+ type Experiment,
109
+ type ExperimentResults,
110
+ type ExperimentListResponse,
111
+ type DatasetExample as EvaluationDatasetExample,
112
+ type ExamplesListResponse,
113
+ type ExampleData,
114
+ type KpiAggregate,
115
+ type KpiAggregateListResponse,
116
+ type KpiAlert,
117
+ type KpiAlertListResponse
118
+ } from "./modules/evaluation.js";
119
+ export * from "./modules/improvements.js";
102
120
  export * from "./modules/me.js";
103
121
  export * from "./modules/members.js";
122
+ export * from "./modules/metaAgent.js";
104
123
  export * from "./modules/observability.js";
105
124
  export * from "./modules/presets.js";
106
125
  export * from "./modules/prompts.js";
107
126
  export * from "./modules/roles.js";
108
127
  export * from "./modules/runs.js";
128
+ export * from "./modules/templates.js";
109
129
  export * from "./modules/triggers.js";
110
130
  export * from "./modules/usage.js";
111
131
  export * from "./modules/workspaces.js";
@@ -53,6 +53,22 @@ export interface GraphValidationResponse {
53
53
  warnings?: string[];
54
54
  }
55
55
 
56
+ export interface AgentDraftIrResponse {
57
+ id: string;
58
+ name: string;
59
+ draft_ir_revision?: string | null;
60
+ draftIrRevision?: string | null;
61
+ draft_updated_at?: string | null;
62
+ draftUpdatedAt?: string | null;
63
+ live_bundle_id?: string | null;
64
+ liveBundleId?: string | null;
65
+ etag?: string;
66
+ e_tag?: string;
67
+ eTag?: string;
68
+ ir_json?: Record<string, unknown> | null;
69
+ irJson?: Record<string, unknown> | null;
70
+ }
71
+
56
72
  export interface UpsertAgentCredentialBindingRequest {
57
73
  credential_id: string;
58
74
  alias: string;
@@ -274,24 +290,64 @@ export class AgentsModule {
274
290
  });
275
291
  }
276
292
 
293
+ // ======================== Draft IR ========================
294
+
295
+ async getDraftIr(agentId: string): Promise<APIResponse<AgentDraftIrResponse>> {
296
+ return this.client.GET<AgentDraftIrResponse>("/v1/api/agents/{id}/draft/ir", {
297
+ params: { path: { id: agentId } },
298
+ headers: this.headers(),
299
+ });
300
+ }
301
+
302
+ async updateDraftIr(
303
+ agentId: string,
304
+ irJson: Record<string, unknown>,
305
+ options?: { if_match?: string }
306
+ ): Promise<APIResponse<AgentDraftIrResponse>> {
307
+ const headers: Record<string, string> = { ...this.headers() };
308
+ if (options?.if_match) {
309
+ headers["If-Match"] = options.if_match;
310
+ }
311
+
312
+ const response = await this.client.PUT<AgentDraftIrResponse | { data?: AgentDraftIrResponse }>("/v1/api/agents/{id}/draft/ir", {
313
+ params: { path: { id: agentId } },
314
+ body: {
315
+ ir_json: irJson,
316
+ } as any,
317
+ headers,
318
+ });
319
+
320
+ const unwrapped =
321
+ response.data &&
322
+ typeof response.data === "object" &&
323
+ "data" in response.data &&
324
+ typeof (response.data as { data?: unknown }).data === "object"
325
+ ? ((response.data as { data?: AgentDraftIrResponse }).data ?? undefined)
326
+ : (response.data as AgentDraftIrResponse | undefined);
327
+
328
+ return {
329
+ ...response,
330
+ data: unwrapped,
331
+ };
332
+ }
333
+
277
334
  // ======================== Publishing ========================
278
335
 
279
336
  /**
280
- * Publish a new version (bundle) of the agent.
337
+ * Publish the committed agent artifact pointed to by the current authoring revision.
338
+ * The client does not send authoring JSON anymore.
281
339
  * @param agentId The agent UUID
282
- * @param graph_spec The graph specification to publish
283
340
  * @param options Optional settings: version_label for tagging, set_as_live to make this the active version, idempotency_key for safe retries
284
341
  * @returns Bundle response with version details
285
342
  * @example
286
343
  * ```ts
287
- * const { data: bundle } = await client.agents.publish(agentId, graphSpec, {
344
+ * const { data: bundle } = await client.agents.publish(agentId, {
288
345
  * idempotency_key: "publish-unique-key"
289
346
  * });
290
347
  * ```
291
348
  */
292
349
  async publish(
293
350
  agentId: string,
294
- graph_spec: Record<string, unknown>,
295
351
  options?: {
296
352
  version_label?: string | null;
297
353
  set_as_live?: boolean;
@@ -308,7 +364,6 @@ export class AgentsModule {
308
364
  return this.client.POST<components["schemas"]["BundleResponse"]>("/v1/api/agents/{id}/publish", {
309
365
  params: { path: { id: agentId } },
310
366
  body: {
311
- graph_spec,
312
367
  version_label: options?.version_label ?? null,
313
368
  set_as_live: options?.set_as_live ?? true,
314
369
  required_tools: options?.required_tools ?? []
@@ -321,11 +376,11 @@ export class AgentsModule {
321
376
 
322
377
  /**
323
378
  * Get the manifest for a specific bundle.
324
- * Returns artifact metadata and graph_spec.
379
+ * Returns artifact metadata only.
325
380
  * @example
326
381
  * ```ts
327
382
  * const { data } = await client.agents.getBundleManifest(agentId, bundleId);
328
- * console.log(data?.graph_spec);
383
+ * console.log(data?.artifact_hash);
329
384
  * ```
330
385
  */
331
386
  async getBundleManifest(agentId: string, bundleId: string): Promise<APIResponse<BundleManifestResponse>> {
@@ -376,7 +431,6 @@ export interface BundleManifestResponse {
376
431
  format?: string;
377
432
  schema_version?: string;
378
433
  created_at?: string;
379
- graph_spec?: Record<string, unknown>;
380
434
  }
381
435
 
382
436
  export interface BundleMermaidResponse {
@@ -0,0 +1,80 @@
1
+ import type { APIResponse, RawClient } from "../client/raw.js";
2
+
3
+ export interface ContractsValidationIssue {
4
+ code: string;
5
+ message: string;
6
+ path?: string;
7
+ severity?: string;
8
+ }
9
+
10
+ export type ContractsErrorCode =
11
+ | "CONTRACT_ID_INVALID"
12
+ | "RUNTIME_PACKAGE_COMPILE_INVALID"
13
+ | "INTERNAL_UNAUTHORIZED"
14
+ | "KERNEL_UNAVAILABLE"
15
+ | "KERNEL_ERROR"
16
+ | "INTERNAL_ERROR"
17
+ | "VALIDATION_ERROR";
18
+
19
+ export interface ContractsErrorResponse {
20
+ code: ContractsErrorCode;
21
+ message: string;
22
+ errors?: ContractsValidationIssue[];
23
+ supported_contract_ids?: string[];
24
+ }
25
+
26
+ export interface ContractsSupportedResponse {
27
+ contract_ids: string[];
28
+ }
29
+
30
+ export interface ContractsValidateRequest {
31
+ contract_id: string;
32
+ spec: unknown;
33
+ }
34
+
35
+ export interface ContractsValidateResponse {
36
+ contract_id: string;
37
+ valid: boolean;
38
+ errors: ContractsValidationIssue[];
39
+ warnings: ContractsValidationIssue[];
40
+ }
41
+
42
+ export interface ContractsCompileRuntimePackageRequest {
43
+ ir_spec: unknown;
44
+ capability_registry_spec: unknown;
45
+ policy_refs?: Record<string, unknown>;
46
+ runtime_config_refs?: Record<string, unknown>;
47
+ package_id?: string;
48
+ metadata?: Record<string, unknown>;
49
+ compiled_at?: string;
50
+ }
51
+
52
+ export interface ContractsCompileRuntimePackageResponse {
53
+ package_spec: Record<string, unknown>;
54
+ }
55
+
56
+ export class ContractsModule {
57
+ constructor(private client: RawClient, private headers: () => Record<string, string>) {}
58
+
59
+ async supported(): Promise<APIResponse<ContractsSupportedResponse>> {
60
+ return this.client.GET<ContractsSupportedResponse>("/v1/api/contracts/supported", {
61
+ headers: this.headers(),
62
+ });
63
+ }
64
+
65
+ async validate(body: ContractsValidateRequest): Promise<APIResponse<ContractsValidateResponse>> {
66
+ return this.client.POST<ContractsValidateResponse>("/v1/api/contracts/validate", {
67
+ body,
68
+ headers: this.headers(),
69
+ });
70
+ }
71
+
72
+ async compileRuntimePackage(
73
+ body: ContractsCompileRuntimePackageRequest,
74
+ ): Promise<APIResponse<ContractsCompileRuntimePackageResponse>> {
75
+ return this.client.POST<ContractsCompileRuntimePackageResponse>("/v1/api/contracts/compile/runtime-package", {
76
+ body,
77
+ headers: this.headers(),
78
+ });
79
+ }
80
+ }
@@ -63,6 +63,52 @@ export interface ExamplesListResponse {
63
63
  total: number;
64
64
  }
65
65
 
66
+ export interface KpiAggregate {
67
+ kpi_key: string;
68
+ kpi_binding_version: string;
69
+ source_scope: string;
70
+ unit?: string | null;
71
+ events_n: number;
72
+ runs_n: number;
73
+ threads_n: number;
74
+ outcome_linked_n: number;
75
+ numeric_values_n: number;
76
+ value_number_sum?: number | null;
77
+ value_number_avg?: number | null;
78
+ value_number_min?: number | null;
79
+ value_number_max?: number | null;
80
+ first_recorded_at: string;
81
+ last_recorded_at: string;
82
+ }
83
+
84
+ export interface KpiAggregateListResponse {
85
+ items: KpiAggregate[];
86
+ total: number;
87
+ skip: number;
88
+ take: number;
89
+ }
90
+
91
+ export interface KpiAlert {
92
+ alert_code: string;
93
+ severity: "critical" | "warning" | "info";
94
+ kpi_key: string;
95
+ kpi_binding_version?: string | null;
96
+ source_scope?: string | null;
97
+ message: string;
98
+ events_n: number;
99
+ numeric_values_n: number;
100
+ outcome_linked_n: number;
101
+ first_recorded_at?: string | null;
102
+ last_recorded_at?: string | null;
103
+ }
104
+
105
+ export interface KpiAlertListResponse {
106
+ items: KpiAlert[];
107
+ total: number;
108
+ skip: number;
109
+ take: number;
110
+ }
111
+
66
112
  export class EvaluationModule {
67
113
  constructor(private client: RawClient, private headers: () => Record<string, string>) { }
68
114
 
@@ -186,4 +232,38 @@ export class EvaluationModule {
186
232
  headers: this.headers(),
187
233
  });
188
234
  }
235
+
236
+ async listKpiAggregates(params?: {
237
+ runId?: string;
238
+ threadId?: string;
239
+ kpiKey?: string;
240
+ kpiBindingVersion?: string;
241
+ sourceScope?: string;
242
+ recordedAfter?: string;
243
+ recordedBefore?: string;
244
+ skip?: number;
245
+ take?: number;
246
+ }): Promise<APIResponse<KpiAggregateListResponse>> {
247
+ return this.client.GET<KpiAggregateListResponse>("/v1/api/evaluations/kpi-results/aggregates", {
248
+ params: { query: params },
249
+ headers: this.headers(),
250
+ });
251
+ }
252
+
253
+ async listKpiAlerts(params?: {
254
+ runId?: string;
255
+ threadId?: string;
256
+ kpiKey?: string;
257
+ sourceScope?: string;
258
+ recordedAfter?: string;
259
+ recordedBefore?: string;
260
+ staleAfterHours?: number;
261
+ skip?: number;
262
+ take?: number;
263
+ }): Promise<APIResponse<KpiAlertListResponse>> {
264
+ return this.client.GET<KpiAlertListResponse>("/v1/api/evaluations/kpi-results/alerts", {
265
+ params: { query: params },
266
+ headers: this.headers(),
267
+ });
268
+ }
189
269
  }
@@ -0,0 +1,71 @@
1
+ import type { APIResponse, RawClient } from "../client/raw.js";
2
+
3
+ export interface ImprovementCase {
4
+ id: string;
5
+ tenant_id: string;
6
+ workspace_id: string;
7
+ agent_id: string;
8
+ champion_bundle_id: string;
9
+ challenger_bundle_id: string;
10
+ eval_experiment_id?: string | null;
11
+ status: string;
12
+ trigger_kind: string;
13
+ improvement_policy_ref?: string | null;
14
+ summary?: string | null;
15
+ decision_comparison_id?: string | null;
16
+ approval_decision_reason?: string | null;
17
+ promotion_decision_reason?: string | null;
18
+ rejection_reason?: string | null;
19
+ rollback_reason?: string | null;
20
+ rollback_decision_comparison_id?: string | null;
21
+ rollback_source_bundle_id?: string | null;
22
+ rollback_target_bundle_id?: string | null;
23
+ created_by?: string | null;
24
+ approved_by?: string | null;
25
+ promoted_by?: string | null;
26
+ rejected_by?: string | null;
27
+ rolled_back_by?: string | null;
28
+ created_at: string;
29
+ updated_at: string;
30
+ approved_at?: string | null;
31
+ promoted_at?: string | null;
32
+ rejected_at?: string | null;
33
+ rolled_back_at?: string | null;
34
+ }
35
+
36
+ export interface ImprovementCaseListResponse {
37
+ items: ImprovementCase[];
38
+ total: number;
39
+ skip: number;
40
+ take: number;
41
+ }
42
+
43
+ export class ImprovementsModule {
44
+ constructor(private client: RawClient, private headers: () => Record<string, string>) {}
45
+
46
+ async list(params?: {
47
+ agentId?: string;
48
+ status?: string;
49
+ skip?: number;
50
+ take?: number;
51
+ }): Promise<APIResponse<ImprovementCaseListResponse>> {
52
+ return this.client.GET<ImprovementCaseListResponse>("/v1/api/improvements/cases", {
53
+ params: {
54
+ query: {
55
+ agentId: params?.agentId,
56
+ status: params?.status,
57
+ skip: params?.skip,
58
+ take: params?.take,
59
+ },
60
+ },
61
+ headers: this.headers(),
62
+ });
63
+ }
64
+
65
+ async get(caseId: string): Promise<APIResponse<ImprovementCase>> {
66
+ return this.client.GET<ImprovementCase>("/v1/api/improvements/cases/{caseId}", {
67
+ params: { path: { caseId } },
68
+ headers: this.headers(),
69
+ });
70
+ }
71
+ }
@@ -0,0 +1,87 @@
1
+ import type { APIResponse, RawClient } from "../client/raw.js";
2
+
3
+ export interface MetaAgentPatchValidationIssue {
4
+ code: string;
5
+ message: string;
6
+ node_id?: string | null;
7
+ path?: string | null;
8
+ }
9
+
10
+ export interface MetaAgentPreviewValidationIssue {
11
+ code: string;
12
+ message: string;
13
+ path?: string | null;
14
+ severity?: string | null;
15
+ }
16
+
17
+ export interface MetaAgentPatchOp {
18
+ op: string;
19
+ node_id?: string | null;
20
+ kind?: string | null;
21
+ label?: string | null;
22
+ data?: Record<string, unknown> | null;
23
+ set?: Record<string, unknown> | null;
24
+ from?: string | null;
25
+ to?: string | null;
26
+ entrypoint?: string | null;
27
+ }
28
+
29
+ export interface MetaAgentPatchProposal {
30
+ patch_id: string;
31
+ description?: string | null;
32
+ ops: MetaAgentPatchOp[];
33
+ }
34
+
35
+ export interface MetaAgentPatchProposalResponse {
36
+ agent_id: string;
37
+ draft_revision?: string | null;
38
+ draft_etag: string;
39
+ source_contract: "agent_ir.v1";
40
+ patch?: MetaAgentPatchProposal | null;
41
+ preview_draft_ir?: Record<string, unknown> | null;
42
+ preview_valid: boolean;
43
+ preview_errors: MetaAgentPreviewValidationIssue[];
44
+ preview_warnings: MetaAgentPreviewValidationIssue[];
45
+ valid: boolean;
46
+ errors: MetaAgentPatchValidationIssue[];
47
+ message: string;
48
+ }
49
+
50
+ export interface MetaAgentApplyPatchResponse {
51
+ agent_id: string;
52
+ draft_revision?: string | null;
53
+ draft_etag_before: string;
54
+ draft_etag_after: string;
55
+ patch_id: string;
56
+ source_contract: "agent_ir.v1";
57
+ applied_at: string;
58
+ applied_by?: string | null;
59
+ draft_ir: Record<string, unknown>;
60
+ }
61
+
62
+ export class MetaAgentModule {
63
+ constructor(private client: RawClient, private headers: () => Record<string, string>) {}
64
+
65
+ async propose(agentId: string, instruction: string): Promise<APIResponse<MetaAgentPatchProposalResponse>> {
66
+ return this.client.POST<MetaAgentPatchProposalResponse>("/v1/api/agents/{id}/meta-agent/proposals", {
67
+ params: { path: { id: agentId } },
68
+ headers: this.headers(),
69
+ body: { instruction },
70
+ });
71
+ }
72
+
73
+ async apply(
74
+ agentId: string,
75
+ draftEtag: string,
76
+ patch: MetaAgentPatchProposal,
77
+ ): Promise<APIResponse<MetaAgentApplyPatchResponse>> {
78
+ return this.client.POST<MetaAgentApplyPatchResponse>("/v1/api/agents/{id}/meta-agent/proposals/apply", {
79
+ params: { path: { id: agentId } },
80
+ headers: this.headers(),
81
+ body: {
82
+ draft_etag: draftEtag,
83
+ patch,
84
+ },
85
+ });
86
+ }
87
+ }
@@ -32,56 +32,111 @@ const TRIGGER_TYPE_MAP: Record<string, { type: string; template_slug: string }>
32
32
  schedule: { type: "schedule", template_slug: "cron" },
33
33
  };
34
34
 
35
- const OUTPUT_NODE_MAP: Record<string, { kind: string; config: Record<string, unknown> }> = {
36
- chatwoot: { kind: "output.chatwoot", config: {} },
37
- http: { kind: "output.http", config: {} },
38
- };
35
+ function buildAgentDefinitionId(name: string): string {
36
+ const normalized = name
37
+ .trim()
38
+ .toLowerCase()
39
+ .replace(/[^a-z0-9]+/g, ".")
40
+ .replace(/\.{2,}/g, ".")
41
+ .replace(/^\.|\.$/g, "");
42
+ return `agent.${normalized || "untitled"}`;
43
+ }
39
44
 
40
- function generateGraphSpec(config: AgentTemplateConfig): Record<string, unknown> {
41
- const triggerMapping = TRIGGER_TYPE_MAP[config.trigger_type] ?? TRIGGER_TYPE_MAP.webhook;
42
- const outputMapping = OUTPUT_NODE_MAP[config.output_type] ?? OUTPUT_NODE_MAP.http;
43
-
44
- // Safe validation (TS knows these keys exist in the constant, but runtime check is good practice)
45
- if (!triggerMapping) throw new Error(`Invalid trigger type: ${config.trigger_type}`);
46
- if (!outputMapping) throw new Error(`Invalid output type: ${config.output_type}`);
47
-
48
- const nodes = [
49
- {
50
- id: "node-llm",
51
- kind: "llm.chat",
52
- label: "LLM",
53
- config: {
54
- model: config.llm?.model || "gpt-4o",
55
- system_prompt: config.llm?.system_prompt || "You are a helpful assistant.",
56
- ...(config.llm?.credential_id ? { credential_id: config.llm.credential_id } : {}),
45
+ function generateAgentIr(config: AgentTemplateConfig): Record<string, unknown> {
46
+ const agentDefinitionId = buildAgentDefinitionId(config.name);
47
+ const triggerLabel = config.trigger_type === "schedule" ? "Scheduled Trigger" : "Incoming Trigger";
48
+ const outputLabel = config.output_type === "chatwoot" ? "Chatwoot Output" : "HTTP Output";
49
+
50
+ return {
51
+ ir_version: "1.0",
52
+ agent_definition_id: agentDefinitionId,
53
+ version: "1.0.0",
54
+ metadata: {
55
+ name: config.name,
56
+ description: "Preset-generated agent_ir.v1 draft",
57
+ },
58
+ state_schema: {
59
+ type: "object",
60
+ properties: {
61
+ global: {
62
+ type: "object",
63
+ },
57
64
  },
58
- ui: { x: 300, y: 200 },
59
65
  },
60
- {
61
- id: "node-output",
62
- ...outputMapping,
63
- label: "Output",
64
- ui: { x: 500, y: 200 },
66
+ inputs_schema: {
67
+ type: "object",
68
+ properties: {
69
+ message: {
70
+ type: "string",
71
+ },
72
+ },
73
+ required: ["message"],
65
74
  },
66
- ];
67
-
68
- const edges = [
69
- { from: "node-llm", to: "node-output" },
70
- ];
71
-
72
- const triggers = [
73
- {
74
- type: `${triggerMapping.template_slug}.${triggerMapping.type}`,
75
- config: { events: ["message_created"] },
75
+ outputs_schema: {
76
+ type: "object",
76
77
  },
77
- ];
78
-
79
- return {
80
- version: "1",
81
- entrypoint: "node-llm",
82
- nodes,
83
- edges,
84
- triggers,
78
+ outcome_schema: {
79
+ type: "object",
80
+ properties: {
81
+ preset_ready: {
82
+ type: "boolean",
83
+ },
84
+ },
85
+ required: ["preset_ready"],
86
+ },
87
+ kpi_bindings: [
88
+ {
89
+ kpi_ref: `${agentDefinitionId}.preset_ready`,
90
+ source_scope: "outcome",
91
+ source_path: "preset_ready",
92
+ },
93
+ ],
94
+ evaluation_policy: {
95
+ execution_mode: "async",
96
+ evaluators: [
97
+ {
98
+ evaluator_ref: `eval.${agentDefinitionId}.preset_shape_v1`,
99
+ kind: "rule",
100
+ },
101
+ ],
102
+ sampling_policy: {
103
+ mode: "all",
104
+ },
105
+ },
106
+ improvement_policy_ref: null,
107
+ nodes: [
108
+ {
109
+ id: "start",
110
+ kind: "start",
111
+ label: triggerLabel,
112
+ config: {},
113
+ bindings: {},
114
+ editability: { mode: "read_only" },
115
+ },
116
+ {
117
+ id: "draft_output",
118
+ kind: "end",
119
+ label: outputLabel,
120
+ config: {},
121
+ bindings: {},
122
+ editability: { mode: "full" },
123
+ },
124
+ ],
125
+ edges: [
126
+ {
127
+ id: "edge_start_to_output",
128
+ from: "start",
129
+ to: "draft_output",
130
+ kind: "default",
131
+ priority: 0,
132
+ },
133
+ ],
134
+ capability_registry_refs: [],
135
+ policies: {},
136
+ editability: {
137
+ mode: "full",
138
+ },
139
+ entrypoints: ["start"],
85
140
  };
86
141
  }
87
142
 
@@ -129,14 +184,27 @@ export class PresetsModule {
129
184
  return null;
130
185
  }
131
186
 
132
- const graphSpec = generateGraphSpec(config);
133
-
134
- const { data: bundle, error: publishError } = await this._agents.publish(
187
+ const { error: draftError } = await this._agents.updateDraftIr(
135
188
  agent.id,
136
- graphSpec,
137
- { set_as_live: true, idempotency_key: generateUUID() }
189
+ generateAgentIr(config),
190
+ { if_match: `"${agent.id}:0"` },
138
191
  );
139
192
 
193
+ if (draftError) {
194
+ console.error("[AgentOS SDK] Failed to save agent_ir.v1 draft:", draftError);
195
+ return {
196
+ agent_id: agent.id,
197
+ agent_name: agent.name,
198
+ status: "draft",
199
+ };
200
+ }
201
+
202
+ const { data: bundle, error: publishError } = await this._agents.publish(agent.id, {
203
+ set_as_live: true,
204
+ required_tools: [],
205
+ idempotency_key: generateUUID(),
206
+ });
207
+
140
208
  if (publishError) {
141
209
  console.error("[AgentOS SDK] Failed to publish bundle:", publishError);
142
210
  return {