@ziggs-ai/agent-sdk 0.34.0 → 0.34.1

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.
@@ -36,7 +36,7 @@ interface ProtocolPayload {
36
36
  })[];
37
37
  [key: string]: unknown;
38
38
  }
39
- export declare function dispatchProtocolOp(services: Services, payload: ProtocolPayload, chatId: string | null, agents?: unknown[], actingAgentId?: string | null, writeKeys?: DeliveryWriteKeys | null,
39
+ export declare function dispatchProtocolOp(services: Services, payload: ProtocolPayload, chatId: string | null, _agents?: unknown[], actingAgentId?: string | null, writeKeys?: DeliveryWriteKeys | null,
40
40
  /** #8 — prefer the cached session snapshot over a fresh HTTP read. */
41
41
  cachedAgreements?: unknown[]): Promise<unknown>;
42
42
  export {};
@@ -1,5 +1,4 @@
1
1
  import { isBroadcastTarget, partyActorIds, presentClaimResult, } from '@ziggs-ai/api-client';
2
- import { applyFleetCounterPricing, applyFleetPricingForProtocol, } from '../../../pricing/fleetDefaults.js';
3
2
  // the link-summary rule lives in AgreementClient, at the point the
4
3
  // document is parsed. Every verb here inherits it through the client instead of
5
4
  // each one restating `engagementKind === 'link' ? linkSummary(a) : a` — which is
@@ -45,7 +44,7 @@ function normalizePlanInPlace(payload) {
45
44
  ? 'before_execution'
46
45
  : 'with_proposal';
47
46
  }
48
- export async function dispatchProtocolOp(services, payload, chatId, agents = [], actingAgentId = null, writeKeys = null,
47
+ export async function dispatchProtocolOp(services, payload, chatId, _agents = [], actingAgentId = null, writeKeys = null,
49
48
  /** #8 — prefer the cached session snapshot over a fresh HTTP read. */
50
49
  cachedAgreements) {
51
50
  if (!payload?.operation)
@@ -55,9 +54,9 @@ cachedAgreements) {
55
54
  const actorId = actingAgentId?.trim() || null;
56
55
  switch (operation) {
57
56
  case 'agreement-propose':
58
- return proposeAgreement(services, payload, chatId, agents, actorId, writeKeys);
57
+ return proposeAgreement(services, payload, chatId, writeKeys);
59
58
  case 'agreement-subcontract':
60
- return subcontractAgreement(services, payload, namedSubcontractChat(payload, chatId), actorId, writeKeys);
59
+ return subcontractAgreement(services, payload, namedSubcontractChat(payload, chatId), writeKeys);
61
60
  case 'agreement-respond':
62
61
  if (!payload.agreementId || !payload.action)
63
62
  return null;
@@ -85,19 +84,15 @@ cachedAgreements) {
85
84
  case 'agreement-counter-proposal':
86
85
  if (!payload.agreementId)
87
86
  return null;
88
- {
89
- const counterPayload = actorId != null
90
- ? applyFleetCounterPricing(payload, actorId)
91
- : payload;
92
- return agreementService.counter(payload.agreementId, {
93
- price: counterPayload.price,
94
- agreementDescription: counterPayload.agreementDescription,
95
- expiresAt: counterPayload.expiresAt,
96
- lifecycle: counterPayload.lifecycle,
97
- maxExecutions: counterPayload.maxExecutions,
98
- description: counterPayload.description,
99
- });
100
- }
87
+ // The price is the one the model stated; the SDK adds none.
88
+ return agreementService.counter(payload.agreementId, {
89
+ price: payload.price,
90
+ agreementDescription: payload.agreementDescription,
91
+ expiresAt: payload.expiresAt,
92
+ lifecycle: payload.lifecycle,
93
+ maxExecutions: payload.maxExecutions,
94
+ description: payload.description,
95
+ });
101
96
  case 'agreement-check-proposal':
102
97
  if (!payload.agreementId)
103
98
  return null;
@@ -239,7 +234,7 @@ cachedAgreements) {
239
234
  throw new Error(`Unknown protocol operation: ${operation}`);
240
235
  }
241
236
  }
242
- async function proposeAgreement(services, payload, chatId, _agents, actingAgentId, writeKeys = null) {
237
+ async function proposeAgreement(services, payload, chatId, writeKeys = null) {
243
238
  if (!payload.description)
244
239
  throw new Error('agreement-propose requires `description`');
245
240
  if (!payload.proposedTo)
@@ -253,7 +248,9 @@ async function proposeAgreement(services, payload, chatId, _agents, actingAgentI
253
248
  }
254
249
  return services.agreementService.requestLink(payload.proposedTo, payload.description);
255
250
  }
256
- const priced = applyFleetPricingForProtocol('agreement-propose', payload, actingAgentId);
251
+ // The agent sets the price, never the SDK: a proposal carries a price only
252
+ // when the model stated one, and the server falls back to the provider's
253
+ // listing price, then to free.
257
254
  // Wake-derived idempotency key (delivery law): a crash-replay re-issuing this
258
255
  // propose resolves to the already-created agreement server-side instead of
259
256
  // minting a duplicate proposal. Keyed on what the proposal writes, so
@@ -264,25 +261,25 @@ async function proposeAgreement(services, payload, chatId, _agents, actingAgentI
264
261
  description: payload.description,
265
262
  parentAgreementId: payload.parentAgreementId,
266
263
  });
267
- const engagementKind = priced.engagementKind === 'hire' || priced.engagementKind === 'service'
268
- ? priced.engagementKind
264
+ const engagementKind = payload.engagementKind === 'hire' || payload.engagementKind === 'service'
265
+ ? payload.engagementKind
269
266
  : undefined;
270
- const billing = priced['billing'] === 'per_task' || priced['billing'] === 'total'
271
- ? priced['billing']
267
+ const billing = payload['billing'] === 'per_task' || payload['billing'] === 'total'
268
+ ? payload['billing']
272
269
  : undefined;
273
270
  const { agreement, shape } = await services.agreementService.proposeUnified({
274
- proposedTo: priced.proposedTo ?? payload.proposedTo,
271
+ proposedTo: payload.proposedTo,
275
272
  chatId: chatId ?? undefined,
276
- description: String(priced.description ?? payload.description),
277
- providerId: priced.providerId,
278
- price: typeof priced.price === 'number' ? priced.price : undefined,
279
- lifecycle: typeof priced.lifecycle === 'string' ? priced.lifecycle : undefined,
280
- expiresAt: typeof priced.expiresAt === 'string' ? priced.expiresAt : undefined,
281
- maxExecutions: typeof priced.maxExecutions === 'number' ? priced.maxExecutions : undefined,
273
+ description: String(payload.description),
274
+ providerId: payload.providerId,
275
+ price: typeof payload.price === 'number' ? payload.price : undefined,
276
+ lifecycle: typeof payload.lifecycle === 'string' ? payload.lifecycle : undefined,
277
+ expiresAt: typeof payload.expiresAt === 'string' ? payload.expiresAt : undefined,
278
+ maxExecutions: typeof payload.maxExecutions === 'number' ? payload.maxExecutions : undefined,
282
279
  billing,
283
- ...(priced.conversationAllowance !== undefined ? { conversationAllowance: priced.conversationAllowance } : {}),
284
- agreementDescription: priced.agreementDescription,
285
- parentAgreementId: priced.parentAgreementId,
280
+ ...(payload.conversationAllowance !== undefined ? { conversationAllowance: payload.conversationAllowance } : {}),
281
+ agreementDescription: payload.agreementDescription,
282
+ parentAgreementId: payload.parentAgreementId,
286
283
  engagementKind,
287
284
  idempotencyKey,
288
285
  });
@@ -350,11 +347,12 @@ function namedSubcontractChat(payload, wakeChatId) {
350
347
  * request over MCP stays open. A crash replay is still covered by the
351
348
  * wake-derived idempotency key.
352
349
  */
353
- async function subcontractAgreement(services, payload, chatId, actingAgentId, writeKeys = null) {
350
+ async function subcontractAgreement(services, payload, chatId, writeKeys = null) {
354
351
  if (!payload.description || !payload.executorId)
355
352
  return null;
356
- const priced = applyFleetPricingForProtocol('agreement-subcontract', payload, actingAgentId);
357
- const { operation: _op, ...fields } = priced;
353
+ // The price the model stated, or none; the server falls back to the
354
+ // executor's listing price, then to free.
355
+ const { operation: _op, ...fields } = payload;
358
356
  const idempotencyKey = writeKeys?.agreementSubcontractKey({
359
357
  executorId: payload.executorId,
360
358
  description: payload.description,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziggs-ai/agent-sdk",
3
- "version": "0.34.0",
3
+ "version": "0.34.1",
4
4
  "description": "Agent framework SDK for building autonomous agents on the Ziggs platform",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -26,7 +26,7 @@
26
26
  "@anthropic-ai/claude-agent-sdk": "^0.3.284",
27
27
  "@anthropic-ai/sdk": "^0.110.0",
28
28
  "@modelcontextprotocol/sdk": "^1.29.0",
29
- "@ziggs-ai/api-client": "0.33.0",
29
+ "@ziggs-ai/api-client": "0.33.1",
30
30
  "ajv": "^8.17.1",
31
31
  "dotenv": "^17.2.3",
32
32
  "openai": "^4.0.0",
@@ -1,42 +0,0 @@
1
- /**
2
- * default paid pricing for Ziggs-operated (first-party) agents.
3
- * Prices are in wallet cents (1 ZIG = 100 cents).
4
- */
5
- import { type FleetPricingTier } from './fleetTierByAgentId.gen.js';
6
- export declare const ZIGGS_OPERATOR_CUT_BPS = 1000;
7
- export declare const TIER_PRICE_CENTS: Record<FleetPricingTier, number>;
8
- export declare function resolveFleetTier(agentId: string): FleetPricingTier | null;
9
- export declare function isFirstPartyFleetAgent(agentId: string): boolean;
10
- export declare function tierPriceCents(tier: FleetPricingTier): number;
11
- export declare function isFreeAllowlistedExecutor(executorId: string, description?: string | null): boolean;
12
- export declare function resolveDefaultPriceCentsForExecutor(executorId: string, description?: string | null): number | null;
13
- export interface ProtocolPricingPayload {
14
- price?: number | null;
15
- description?: string;
16
- agreementDescription?: string;
17
- proposedTo?: string;
18
- providerId?: string;
19
- executorId?: string;
20
- parentAgreementId?: string;
21
- [key: string]: unknown;
22
- }
23
- /**
24
- * Apply defaults when `price` is omitted (null/undefined).
25
- * Explicit `price: 0` is kept (free-on-purpose).
26
- */
27
- export declare function applyFleetAgreementPricing(operation: 'agreement-propose' | 'agreement-subcontract', payload: ProtocolPricingPayload, actingAgentId: string): ProtocolPricingPayload;
28
- /**
29
- * Default tier price when a fleet agent counters without an explicit `price`.
30
- *
31
- * Generic over the payload shape so the precise field types of the caller's
32
- * payload survive the round-trip — this helper only ever sets `price`, so a
33
- * richer input type (e.g. protocolRunner's `ProtocolPayload`) must come back
34
- * out unwidened by `ProtocolPricingPayload`'s `[key: string]: unknown` index.
35
- */
36
- export declare function applyFleetCounterPricing<T extends ProtocolPricingPayload>(payload: T, actingAgentId: string): T;
37
- /**
38
- * Infer fleet actor when tool context omits agentId (safety net).
39
- */
40
- export declare function inferFleetPricingActorId(payload: ProtocolPricingPayload): string | null;
41
- /** Apply fleet defaults with optional acting agent (falls back to payload inference). */
42
- export declare function applyFleetPricingForProtocol(operation: 'agreement-propose' | 'agreement-subcontract', payload: ProtocolPricingPayload, actingAgentId: string | null): ProtocolPricingPayload;
@@ -1,152 +0,0 @@
1
- /**
2
- * default paid pricing for Ziggs-operated (first-party) agents.
3
- * Prices are in wallet cents (1 ZIG = 100 cents).
4
- */
5
- import { FLEET_TIER_BY_AGENT_ID } from './fleetTierByAgentId.gen.js';
6
- import { isEvalFreeExecutor } from './fleetEvalFree.js';
7
- export const ZIGGS_OPERATOR_CUT_BPS = 1000; // 10%
8
- export const TIER_PRICE_CENTS = {
9
- A: 200, // 2 ZIG / call
10
- B: 500, // 5 ZIG / call
11
- C: 1500, // 15 ZIG / job (orchestrator, charged once at top)
12
- D: 100, // 1 ZIG / call (hand-written demo agents)
13
- };
14
- const PING_DESCRIPTION_PATTERN = /\b(ping|health\s*check|healthcheck|liveness|readiness|heartbeat)\b/i;
15
- export function resolveFleetTier(agentId) {
16
- if (!agentId || typeof agentId !== 'string')
17
- return null;
18
- return FLEET_TIER_BY_AGENT_ID[agentId] ?? null;
19
- }
20
- export function isFirstPartyFleetAgent(agentId) {
21
- return resolveFleetTier(agentId) != null;
22
- }
23
- export function tierPriceCents(tier) {
24
- return TIER_PRICE_CENTS[tier];
25
- }
26
- export function isFreeAllowlistedExecutor(executorId, description) {
27
- if (!executorId)
28
- return false;
29
- if (isEvalFreeExecutor(executorId))
30
- return true;
31
- // A health check does not bill, whatever tier the executor is in. This is
32
- // the only description-based exemption left: an agent whose work should cost
33
- // nothing says so with a posted price of 0 on its own listing, where the
34
- // buyer can see it, rather than through a rule inferred here.
35
- if (description && PING_DESCRIPTION_PATTERN.test(description))
36
- return true;
37
- return false;
38
- }
39
- export function resolveDefaultPriceCentsForExecutor(executorId, description) {
40
- if (isFreeAllowlistedExecutor(executorId, description))
41
- return 0;
42
- const tier = resolveFleetTier(executorId);
43
- if (!tier)
44
- return null;
45
- return tierPriceCents(tier);
46
- }
47
- /**
48
- * Apply defaults when `price` is omitted (null/undefined).
49
- * Explicit `price: 0` is kept (free-on-purpose).
50
- */
51
- export function applyFleetAgreementPricing(operation, payload, actingAgentId) {
52
- if (payload.price != null && payload.price !== undefined) {
53
- return payload;
54
- }
55
- const next = { ...payload };
56
- const scopeDescription = next.description ?? next.agreementDescription;
57
- if (operation === 'agreement-subcontract') {
58
- const executorId = String(next.executorId ?? '');
59
- if (next.parentAgreementId) {
60
- // Paid parent scope: no second user hold — allocate from parent budget (recordAllocation).
61
- const cents = resolveDefaultPriceCentsForExecutor(executorId, scopeDescription);
62
- next.price = cents ?? 0;
63
- return next;
64
- }
65
- const cents = resolveDefaultPriceCentsForExecutor(executorId, scopeDescription);
66
- if (cents != null)
67
- next.price = cents;
68
- return next;
69
- }
70
- // agreement-propose
71
- if (next.parentAgreementId) {
72
- return next;
73
- }
74
- const proposedTo = next.proposedTo != null ? String(next.proposedTo) : '';
75
- const providerId = next.providerId != null ? String(next.providerId) : '';
76
- // A tier C orchestrator proposing scope to a user — 15 ZIG once at top.
77
- //
78
- // The ziggs delegate used to have its own branch above this one, keyed on a
79
- // hardcoded id. It asked the same question with the same answer — that agent
80
- // is tier C, so this line already priced it. A second way of asking the tier
81
- // question the tier had already answered, which is the same shape that was
82
- // removed from the backend copy.
83
- const actingTier = resolveFleetTier(actingAgentId);
84
- if (actingTier === 'C' && proposedTo && !isFirstPartyFleetAgent(proposedTo)) {
85
- next.price = TIER_PRICE_CENTS.C;
86
- return next;
87
- }
88
- // Matchmaking: propose directly to a fleet specialist with tier list price.
89
- const specialistId = providerId || (isFirstPartyFleetAgent(proposedTo) ? proposedTo : '');
90
- if (specialistId) {
91
- const cents = resolveDefaultPriceCentsForExecutor(specialistId, scopeDescription);
92
- if (cents != null)
93
- next.price = cents;
94
- }
95
- return next;
96
- }
97
- /**
98
- * Default tier price when a fleet agent counters without an explicit `price`.
99
- *
100
- * Generic over the payload shape so the precise field types of the caller's
101
- * payload survive the round-trip — this helper only ever sets `price`, so a
102
- * richer input type (e.g. protocolRunner's `ProtocolPayload`) must come back
103
- * out unwidened by `ProtocolPricingPayload`'s `[key: string]: unknown` index.
104
- */
105
- export function applyFleetCounterPricing(payload, actingAgentId) {
106
- if (payload.price != null && payload.price !== undefined) {
107
- return payload;
108
- }
109
- const cents = resolveDefaultPriceCentsForExecutor(actingAgentId, payload.description ?? payload.agreementDescription);
110
- if (cents == null)
111
- return payload;
112
- return { ...payload, price: cents };
113
- }
114
- /**
115
- * Infer fleet actor when tool context omits agentId (safety net).
116
- */
117
- export function inferFleetPricingActorId(payload) {
118
- const executor = payload.executorId != null ? String(payload.executorId) : '';
119
- if (executor && isFirstPartyFleetAgent(executor))
120
- return executor;
121
- const provider = payload.providerId != null ? String(payload.providerId) : '';
122
- if (provider && isFirstPartyFleetAgent(provider))
123
- return provider;
124
- const proposed = payload.proposedTo != null ? String(payload.proposedTo) : '';
125
- if (proposed && isFirstPartyFleetAgent(proposed))
126
- return proposed;
127
- return null;
128
- }
129
- /** Apply fleet defaults with optional acting agent (falls back to payload inference). */
130
- export function applyFleetPricingForProtocol(operation, payload, actingAgentId) {
131
- const actor = actingAgentId?.trim() || inferFleetPricingActorId(payload);
132
- if (!actor) {
133
- if (operation === 'agreement-propose') {
134
- const specialist = (payload.providerId != null ? String(payload.providerId) : '') ||
135
- (payload.proposedTo != null && isFirstPartyFleetAgent(String(payload.proposedTo))
136
- ? String(payload.proposedTo)
137
- : '');
138
- if (specialist) {
139
- const cents = resolveDefaultPriceCentsForExecutor(specialist, payload.description ?? payload.agreementDescription);
140
- if (cents != null)
141
- return { ...payload, price: cents };
142
- }
143
- }
144
- if (operation === 'agreement-subcontract' && payload.executorId) {
145
- const cents = resolveDefaultPriceCentsForExecutor(String(payload.executorId), payload.description);
146
- if (cents != null)
147
- return { ...payload, price: cents };
148
- }
149
- return payload;
150
- }
151
- return applyFleetAgreementPricing(operation, payload, actor);
152
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * eval/harness free pricing via env flag (no SANDBOX id-shape regex).
3
- */
4
- /** Capability-probe + test harness agents (agents/test/). */
5
- export declare const EVAL_HARNESS_AGENT_IDS: Set<string>;
6
- export declare function isEvalFreePricingEnabled(): boolean;
7
- export declare function isEvalFreeExecutor(agentId: string): boolean;
@@ -1,23 +0,0 @@
1
- /**
2
- * eval/harness free pricing via env flag (no SANDBOX id-shape regex).
3
- */
4
- /** Capability-probe + test harness agents (agents/test/). */
5
- export const EVAL_HARNESS_AGENT_IDS = new Set([
6
- 'minimal-context-agent',
7
- 'forwarding-agent',
8
- 'failing-agent',
9
- 'principal-agent',
10
- 'capability-probe-agent',
11
- ]);
12
- export function isEvalFreePricingEnabled() {
13
- return process.env.FLEET_EVAL_FREE_PRICING === 'true';
14
- }
15
- export function isEvalFreeExecutor(agentId) {
16
- if (!isEvalFreePricingEnabled() || !agentId)
17
- return false;
18
- if (agentId === 'eval-user')
19
- return true;
20
- if (agentId.endsWith('--eval'))
21
- return true;
22
- return EVAL_HARNESS_AGENT_IDS.has(agentId);
23
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * AUTO-GENERATED by scripts/build-fleet-tier-map.mjs — do not edit by hand.
3
- * Local default pricing; the server resolves an agent's own pricing tier.
4
- */
5
- export type FleetPricingTier = 'A' | 'B' | 'C' | 'D';
6
- export declare const FLEET_TIER_BY_AGENT_ID: Record<string, FleetPricingTier>;
7
- export declare const FLEET_TIER_MAP_SIZE = 17;
@@ -1,20 +0,0 @@
1
- export const FLEET_TIER_BY_AGENT_ID = {
2
- "ziggs-agent": "C",
3
- "ziggs-agent--eval": "C",
4
- "coffee-agent": "D",
5
- "coffee-agent--eval": "D",
6
- "delivery-agent": "D",
7
- "delivery-agent--eval": "D",
8
- "expense-agent": "D",
9
- "fruit-agent": "D",
10
- "vendor-agent": "D",
11
- "shopper-agent": "D",
12
- "hire-agent": "B",
13
- "ziggs-docs-agent": "B",
14
- "agent-definer": "B",
15
- "linear-janitor": "B",
16
- "shipped-digest": "B",
17
- "docs-reviewer": "B",
18
- "email-agent": "B"
19
- };
20
- export const FLEET_TIER_MAP_SIZE = 17;