@ziggs-ai/agent-sdk 0.1.11 → 0.2.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.
Files changed (211) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +41 -2
  3. package/dist/AgentHost.d.ts +201 -0
  4. package/dist/AgentHost.js +652 -0
  5. package/dist/adapters/AnthropicAdapter.d.ts +39 -0
  6. package/dist/adapters/AnthropicAdapter.js +200 -0
  7. package/dist/adapters/McpAdapter.d.ts +199 -0
  8. package/dist/adapters/McpAdapter.js +468 -0
  9. package/dist/adapters/OpenAIAdapter.d.ts +26 -0
  10. package/dist/adapters/OpenAIAdapter.js +158 -0
  11. package/dist/adapters/index.js +2 -0
  12. package/dist/agent/Agent.d.ts +78 -0
  13. package/dist/agent/Agent.js +58 -0
  14. package/dist/agent/ClaudeSdkAgent.d.ts +38 -0
  15. package/dist/agent/ClaudeSdkAgent.js +322 -0
  16. package/dist/agent/claudeCognition.d.ts +67 -0
  17. package/dist/agent/claudeCognition.js +103 -0
  18. package/dist/agent/claudeSdkProtocol.d.ts +11 -0
  19. package/dist/agent/claudeSdkProtocol.js +27 -0
  20. package/dist/agent/claudeSdkTools.d.ts +19 -0
  21. package/dist/agent/claudeSdkTools.js +57 -0
  22. package/dist/agent/hostedAgentConnection.d.ts +15 -0
  23. package/dist/agent/hostedAgentConnection.js +29 -0
  24. package/dist/agent/toolManagerToSdkMcp.d.ts +12 -0
  25. package/dist/agent/toolManagerToSdkMcp.js +123 -0
  26. package/dist/brain/index.d.ts +50 -0
  27. package/dist/brain/index.js +45 -0
  28. package/dist/cognition/validateContext.d.ts +11 -0
  29. package/dist/cognition/validateContext.js +117 -0
  30. package/dist/context/applyEffects.d.ts +2 -0
  31. package/dist/context/applyEffects.js +89 -0
  32. package/dist/context/batch.d.ts +2 -0
  33. package/dist/context/batch.js +18 -0
  34. package/dist/context/classifyEnvelope.d.ts +1 -0
  35. package/dist/context/classifyEnvelope.js +58 -0
  36. package/dist/context/routingLabels.d.ts +4 -0
  37. package/dist/context/routingLabels.js +48 -0
  38. package/dist/defineAgent.d.ts +14 -0
  39. package/dist/defineAgent.js +68 -0
  40. package/dist/formatters/AgreementFormatter.d.ts +18 -0
  41. package/dist/formatters/AgreementFormatter.js +130 -0
  42. package/dist/formatters/HistoryFormatter.d.ts +26 -0
  43. package/dist/formatters/HistoryFormatter.js +173 -0
  44. package/dist/formatters/index.js +2 -0
  45. package/{src/index.ts → dist/index.d.ts} +13 -53
  46. package/dist/index.js +66 -0
  47. package/dist/ingress/normalizeIncoming.d.ts +65 -0
  48. package/dist/ingress/normalizeIncoming.js +88 -0
  49. package/dist/memory/MemoryStore.d.ts +55 -0
  50. package/dist/memory/MemoryStore.js +78 -0
  51. package/dist/pricing/fleetDefaults.d.ts +46 -0
  52. package/dist/pricing/fleetDefaults.js +168 -0
  53. package/dist/pricing/fleetEvalFree.d.ts +7 -0
  54. package/dist/pricing/fleetEvalFree.js +24 -0
  55. package/dist/pricing/fleetFreeTierA.gen.d.ts +6 -0
  56. package/{src/pricing/fleetFreeTierA.gen.ts → dist/pricing/fleetFreeTierA.gen.js} +5 -6
  57. package/dist/pricing/fleetTierByAgentId.gen.d.ts +7 -0
  58. package/dist/pricing/fleetTierByAgentId.gen.js +768 -0
  59. package/dist/runtime/AgentMachine.d.ts +143 -0
  60. package/dist/runtime/AgentMachine.js +400 -0
  61. package/dist/runtime/PromptBuilder.d.ts +96 -0
  62. package/dist/runtime/PromptBuilder.js +439 -0
  63. package/dist/runtime/bootstrapCtx.d.ts +18 -0
  64. package/dist/runtime/bootstrapCtx.js +37 -0
  65. package/dist/runtime/buildOutcome.d.ts +68 -0
  66. package/dist/runtime/buildOutcome.js +464 -0
  67. package/dist/runtime/defaults.d.ts +54 -0
  68. package/dist/runtime/defaults.js +47 -0
  69. package/dist/runtime/deriveRespondsToProposals.d.ts +9 -0
  70. package/dist/runtime/deriveRespondsToProposals.js +38 -0
  71. package/dist/runtime/kickoff.d.ts +15 -0
  72. package/dist/runtime/kickoff.js +112 -0
  73. package/dist/runtime/runMechanical.d.ts +25 -0
  74. package/dist/runtime/runMechanical.js +74 -0
  75. package/dist/runtime/runTurn.d.ts +63 -0
  76. package/dist/runtime/runTurn.js +800 -0
  77. package/dist/runtime/validateWorkflow.d.ts +17 -0
  78. package/dist/runtime/validateWorkflow.js +209 -0
  79. package/dist/server/ConnectionPool.d.ts +68 -0
  80. package/dist/server/ConnectionPool.js +166 -0
  81. package/dist/server/EventQueue.d.ts +33 -0
  82. package/dist/server/EventQueue.js +98 -0
  83. package/dist/server/InboxCatchUp.d.ts +24 -0
  84. package/dist/server/InboxCatchUp.js +213 -0
  85. package/dist/server/OutboxBuffer.d.ts +33 -0
  86. package/dist/server/OutboxBuffer.js +68 -0
  87. package/dist/server/SeenMessages.d.ts +13 -0
  88. package/dist/server/SeenMessages.js +31 -0
  89. package/dist/server/StateTimers.d.ts +34 -0
  90. package/dist/server/StateTimers.js +70 -0
  91. package/dist/server/ZiggsEffectHandler.d.ts +79 -0
  92. package/dist/server/ZiggsEffectHandler.js +319 -0
  93. package/dist/server/agreements/AgreementService.d.ts +50 -0
  94. package/dist/server/agreements/AgreementService.js +85 -0
  95. package/dist/server/createHealthServer.d.ts +7 -0
  96. package/dist/server/createHealthServer.js +75 -0
  97. package/dist/server/proactive/ProactiveTrigger.d.ts +33 -0
  98. package/dist/server/proactive/ProactiveTrigger.js +71 -0
  99. package/dist/server/runLauncher.d.ts +28 -0
  100. package/dist/server/runLauncher.js +93 -0
  101. package/dist/server/tasks/TaskService.d.ts +25 -0
  102. package/dist/server/tasks/TaskService.js +103 -0
  103. package/dist/server/tasks/index.js +1 -0
  104. package/dist/server/telemetryIngest.d.ts +24 -0
  105. package/dist/server/telemetryIngest.js +62 -0
  106. package/dist/server/tools/index.d.ts +24 -0
  107. package/{src/server/tools/index.ts → dist/server/tools/index.js} +4 -24
  108. package/dist/server/tools/tier1/protocolRunner.d.ts +39 -0
  109. package/dist/server/tools/tier1/protocolRunner.js +288 -0
  110. package/dist/server/tools/tier1/protocolTools.d.ts +12 -0
  111. package/dist/server/tools/tier1/protocolTools.js +37 -0
  112. package/dist/server/tools/tier2/connectionTools.d.ts +4 -0
  113. package/dist/server/tools/tier2/connectionTools.js +63 -0
  114. package/dist/server/tools/tier2/contextTools.d.ts +4 -0
  115. package/dist/server/tools/tier2/contextTools.js +46 -0
  116. package/dist/server/tools/tier2/discoveryTools.d.ts +4 -0
  117. package/dist/server/tools/tier2/discoveryTools.js +25 -0
  118. package/dist/server/tools/tier2/marketplaceTools.d.ts +3 -0
  119. package/dist/server/tools/tier2/marketplaceTools.js +22 -0
  120. package/dist/server/tools/tier2/paymentTools.d.ts +12 -0
  121. package/dist/server/tools/tier2/paymentTools.js +165 -0
  122. package/dist/server/ziggsconnect/ZiggsConnectClient.d.ts +35 -0
  123. package/dist/server/ziggsconnect/ZiggsConnectClient.js +95 -0
  124. package/dist/server/ziggscontext/ZiggsContextClient.d.ts +48 -0
  125. package/dist/server/ziggscontext/ZiggsContextClient.js +90 -0
  126. package/dist/server/ziggspay/ZiggsPayClient.d.ts +82 -0
  127. package/dist/server/ziggspay/ZiggsPayClient.js +188 -0
  128. package/dist/shared/ids.d.ts +1 -0
  129. package/dist/shared/ids.js +3 -0
  130. package/dist/shared/runtimeLog.d.ts +18 -0
  131. package/dist/shared/runtimeLog.js +68 -0
  132. package/dist/shared/types.d.ts +22 -0
  133. package/dist/shared/types.js +23 -0
  134. package/dist/tasks/protocolRegistry.d.ts +16 -0
  135. package/dist/tasks/protocolRegistry.js +20 -0
  136. package/dist/tools/ToolManager.d.ts +12 -0
  137. package/dist/tools/ToolManager.js +74 -0
  138. package/dist/tools/ToolProvider.d.ts +6 -0
  139. package/dist/tools/ToolProvider.js +21 -0
  140. package/dist/tools/defineTool.d.ts +27 -0
  141. package/dist/tools/defineTool.js +62 -0
  142. package/{src/tools/index.ts → dist/tools/index.d.ts} +0 -1
  143. package/dist/tools/index.js +6 -0
  144. package/dist/tools/recordReport.d.ts +41 -0
  145. package/dist/tools/recordReport.js +30 -0
  146. package/dist/types.d.ts +466 -0
  147. package/dist/types.js +7 -0
  148. package/dist/utils/jsonExtractor.d.ts +2 -0
  149. package/dist/utils/jsonExtractor.js +111 -0
  150. package/package.json +17 -7
  151. package/src/AgentHost.ts +0 -545
  152. package/src/adapters/AnthropicAdapter.ts +0 -206
  153. package/src/adapters/McpAdapter.ts +0 -348
  154. package/src/adapters/OpenAIAdapter.ts +0 -187
  155. package/src/agent/Agent.ts +0 -104
  156. package/src/cognition/validateContext.ts +0 -95
  157. package/src/context/applyEffects.ts +0 -80
  158. package/src/context/batch.ts +0 -19
  159. package/src/context/classifyEnvelope.ts +0 -38
  160. package/src/context/routingLabels.ts +0 -46
  161. package/src/defineAgent.ts +0 -70
  162. package/src/formatters/AgreementFormatter.ts +0 -111
  163. package/src/formatters/HistoryFormatter.ts +0 -172
  164. package/src/ingress/normalizeIncoming.ts +0 -162
  165. package/src/memory/MemoryStore.ts +0 -104
  166. package/src/pricing/fleetDefaults.ts +0 -225
  167. package/src/pricing/fleetEvalFree.ts +0 -24
  168. package/src/pricing/fleetTierByAgentId.gen.ts +0 -775
  169. package/src/runtime/AgentMachine.ts +0 -402
  170. package/src/runtime/PromptBuilder.ts +0 -485
  171. package/src/runtime/buildOutcome.ts +0 -563
  172. package/src/runtime/defaults.ts +0 -75
  173. package/src/runtime/kickoff.ts +0 -117
  174. package/src/runtime/runTurn.ts +0 -813
  175. package/src/runtime/validateWorkflow.ts +0 -202
  176. package/src/server/ConnectionPool.ts +0 -206
  177. package/src/server/EventQueue.ts +0 -133
  178. package/src/server/InboxCatchUp.ts +0 -254
  179. package/src/server/OutboxBuffer.ts +0 -90
  180. package/src/server/SeenMessages.ts +0 -27
  181. package/src/server/StateTimers.ts +0 -85
  182. package/src/server/ZiggsEffectHandler.ts +0 -418
  183. package/src/server/agreements/AgreementService.ts +0 -118
  184. package/src/server/createHealthServer.ts +0 -85
  185. package/src/server/proactive/ProactiveTrigger.ts +0 -83
  186. package/src/server/runLauncher.ts +0 -146
  187. package/src/server/tasks/TaskService.ts +0 -110
  188. package/src/server/telemetryIngest.ts +0 -91
  189. package/src/server/tools/tier1/protocolRunner.ts +0 -144
  190. package/src/server/tools/tier1/protocolTools.ts +0 -99
  191. package/src/server/tools/tier2/connectionTools.ts +0 -75
  192. package/src/server/tools/tier2/contextTools.ts +0 -63
  193. package/src/server/tools/tier2/discoveryTools.ts +0 -34
  194. package/src/server/tools/tier2/marketplaceTools.ts +0 -27
  195. package/src/server/tools/tier2/paymentTools.ts +0 -170
  196. package/src/server/ziggsconnect/ZiggsConnectClient.ts +0 -126
  197. package/src/server/ziggscontext/ZiggsContextClient.ts +0 -129
  198. package/src/server/ziggspay/ZiggsPayClient.ts +0 -193
  199. package/src/shared/ids.ts +0 -3
  200. package/src/shared/runtimeLog.ts +0 -72
  201. package/src/shared/types.ts +0 -29
  202. package/src/tasks/protocolRegistry.ts +0 -25
  203. package/src/tools/ToolManager.ts +0 -95
  204. package/src/tools/ToolProvider.ts +0 -19
  205. package/src/tools/defineTool.ts +0 -90
  206. package/src/tools/recordReport.ts +0 -82
  207. package/src/types.ts +0 -456
  208. package/src/utils/jsonExtractor.ts +0 -100
  209. /package/{src/adapters/index.ts → dist/adapters/index.d.ts} +0 -0
  210. /package/{src/formatters/index.ts → dist/formatters/index.d.ts} +0 -0
  211. /package/{src/server/tasks/index.ts → dist/server/tasks/index.d.ts} +0 -0
@@ -1,418 +0,0 @@
1
- /**
2
- * Ziggs-flavored EffectHandler.
3
- *
4
- * Translates the Agent's pure Effect requests into concrete calls against
5
- * Ziggs backend primitives (MessagesClient, ArtifactsClient, ScopeClient,
6
- * taskService, agreementService, messageSender) and the OpenAI adapter. This
7
- * is the only place where Agent intent meets backend reality.
8
- *
9
- * Lives in agent-sdk for now alongside `Agent`; destined for a separate
10
- * `@ziggs-ai/agent-server` package once the SDK split is complete.
11
- */
12
- import type {
13
- Effect, EffectHandler,
14
- ContextSnapshot, LlmMessage, LlmResponse, LlmToolSchema, ToolCallResult,
15
- } from '../types.js';
16
- import { OutboxBuffer } from './OutboxBuffer.js';
17
- import { runtimeLog } from '../shared/runtimeLog.js';
18
- /** Minimal LLM adapter contract — OpenAIAdapter satisfies this. */
19
- interface LlmAdapter {
20
- chatMessages(messages: LlmMessage[], tools?: LlmToolSchema[], options?: Record<string, unknown>): Promise<LlmResponse>;
21
- chatMessagesStream?(messages: LlmMessage[], onChunk: (text: string) => void): Promise<string>;
22
- }
23
- import type { TaskService } from './tasks/TaskService.js';
24
- import type { AgreementService } from './agreements/AgreementService.js';
25
- import type { ToolManager } from '../tools/ToolManager.js';
26
- import type {
27
- MessagesClient,
28
- ArtifactsClient,
29
- ScopeClient,
30
- TelemetryClient,
31
- } from '@ziggs-ai/api-client';
32
- import {
33
- buildLlmIngestPayload,
34
- buildToolIngestPayload,
35
- isTelemetryIngestEnabled,
36
- sendTelemetry,
37
- } from './telemetryIngest.js';
38
-
39
- export interface ZiggsEffectDeps {
40
- llm: LlmAdapter;
41
- messagesClient: MessagesClient;
42
- artifactsClient: ArtifactsClient;
43
- scopeClient: ScopeClient;
44
- taskService: TaskService;
45
- agreementService: AgreementService;
46
- messageSender: (text: string, receiverId: string, sessionId: string, messageId?: string) => Promise<unknown>;
47
- /** Sends a streaming chunk to a client. Called per-token during stream-text effects. */
48
- chunkSender?: (sessionId: string, receiverId: string, text: string, messageId: string) => void;
49
- toolManager: ToolManager;
50
- operatorKey: string;
51
- agentId: string;
52
- telemetryClient?: TelemetryClient;
53
- /** When false, skips POST /agents/monitoring/ingest (default: env on). */
54
- telemetryIngest?: boolean;
55
- effectTap?: (effect: Effect, response: unknown) => void;
56
- }
57
-
58
- const CONTEXT_CACHE_MAX = 256;
59
-
60
- /**
61
- * Compose a `ContextSnapshot` for a chatId by fanning out to scope + messages
62
- * primitives. Replaces the single `/context/read` aggregator with parallel
63
- * pulls. The shape stays the same so PromptBuilder / cognition code doesn't
64
- * change.
65
- */
66
- const annotateAgreement = (ag: Record<string, unknown>, agentId: string): Record<string, unknown> => {
67
- const parties = (ag?.parties ?? {}) as { creator?: string; provider?: string; payer?: string; proposedTo?: string };
68
- return {
69
- ...ag,
70
- creatorIsYou: parties.creator === agentId,
71
- providerIsYou: parties.provider === agentId,
72
- payerIsYou: parties.payer === agentId,
73
- proposedToIsYou: parties.proposedTo === agentId,
74
- };
75
- };
76
-
77
- async function buildSnapshot(
78
- deps: ZiggsEffectDeps,
79
- chatId: string,
80
- agentId: string,
81
- opts: { after?: string; limit?: number } = {},
82
- ): Promise<ContextSnapshot> {
83
- const [scope, msgs, chatAgreements] = await Promise.all([
84
- deps.scopeClient.get('chat', chatId).catch((err: unknown) => {
85
- runtimeLog.warn('ZiggsEffectHandler', `scope fetch failed: ${(err as Error)?.message ?? err}`);
86
- return null;
87
- }),
88
- deps.messagesClient
89
- .list(chatId, { after: opts.after, limit: opts.limit })
90
- .catch((err: unknown) => {
91
- runtimeLog.warn('ZiggsEffectHandler', `messages fetch failed: ${(err as Error)?.message ?? err}`);
92
- return { messages: [], latestSequence: null };
93
- }),
94
- deps.agreementService.getByChat(chatId).catch((err: unknown) => {
95
- runtimeLog.warn('ZiggsEffectHandler', `agreements fetch failed: ${(err as Error)?.message ?? err}`);
96
- return [] as unknown[];
97
- }),
98
- ]);
99
-
100
- const counterparties = (scope?.accessible?.counterparties ?? []) as Array<{
101
- id: string;
102
- role: string;
103
- principalType?: 'user' | 'agent';
104
- }>;
105
-
106
- const others = counterparties.filter((c) => c.id !== agentId);
107
- const users = others
108
- .filter((c) => c.principalType === 'user')
109
- .map((c) => ({ userId: c.id, role: c.role }));
110
- const agents = others
111
- .filter((c) => c.principalType !== 'user') // 'agent' or missing → treat as agent
112
- .map((c) => ({ agentId: c.id, role: c.role, isYou: false }));
113
- agents.push({ agentId, role: 'self', isYou: true });
114
-
115
- const agreements = (chatAgreements as Record<string, unknown>[]).map((ag) => annotateAgreement(ag, agentId));
116
-
117
- return {
118
- history: msgs.messages as Record<string, unknown>[],
119
- agreements,
120
- agents,
121
- users,
122
- latestSequence: msgs.latestSequence,
123
- };
124
- }
125
-
126
- const OP_ARTIFACT_MAX_CHARS = 900;
127
-
128
- function clipForOperationArtifact(value: unknown): unknown {
129
- if (value == null) return value;
130
- if (typeof value === 'string') {
131
- return value.length > OP_ARTIFACT_MAX_CHARS ? `${value.slice(0, OP_ARTIFACT_MAX_CHARS - 1)}…` : value;
132
- }
133
- try {
134
- const s = JSON.stringify(value);
135
- if (s.length <= OP_ARTIFACT_MAX_CHARS) return value;
136
- return `${s.slice(0, OP_ARTIFACT_MAX_CHARS - 1)}…`;
137
- } catch {
138
- return String(value).slice(0, OP_ARTIFACT_MAX_CHARS);
139
- }
140
- }
141
-
142
- function previewToolArgs(args: Record<string, unknown>): Record<string, unknown> | undefined {
143
- const keys = Object.keys(args);
144
- if (keys.length === 0) return undefined;
145
- const out: Record<string, unknown> = {};
146
- for (let i = 0; i < keys.length && i < 16; i++) {
147
- const k = keys[i];
148
- out[k] = clipForOperationArtifact(args[k]);
149
- }
150
- return out;
151
- }
152
-
153
- /**
154
- * Chat timeline: `Message.tsx` parses `entryType: artifact`, `content_type: operation` with
155
- * `operation_*:{json}` where json includes `state` and `tool`.
156
- */
157
- async function emitToolOperationArtifact(
158
- client: ArtifactsClient,
159
- chatId: string,
160
- phase: 'started' | 'completed' | 'error',
161
- payload: Record<string, unknown>,
162
- ): Promise<void> {
163
- const prefix =
164
- phase === 'started' ? 'operation_started' : phase === 'completed' ? 'operation_completed' : 'operation_error';
165
- const text = `${prefix}:${JSON.stringify(payload)}`;
166
- try {
167
- await client.write({
168
- chatId,
169
- text,
170
- content_type: 'operation',
171
- visibility: 'agent-private',
172
- });
173
- } catch (e: unknown) {
174
- runtimeLog.warn(
175
- 'ZiggsEffectHandler',
176
- `tool operation artifact (${phase}): ${(e as Error)?.message ?? String(e)}`,
177
- );
178
- }
179
- }
180
-
181
- /**
182
- * Build a single shared EffectHandler. The handler is stateful — it caches
183
- * the latest ContextSnapshot per sessionId so tool-call effects can resolve
184
- * session-coupled deps (the `agents` roster) without forcing the Agent to
185
- * pass them through. Cache is bounded with simple LRU eviction (re-set on
186
- * read promotes the entry; oldest entry drops when size exceeds the cap).
187
- */
188
- export function createZiggsEffectHandler(deps: ZiggsEffectDeps): EffectHandler {
189
- const contextCache = new Map<string, ContextSnapshot>();
190
- const outbox = new OutboxBuffer();
191
-
192
- const cachePut = (sessionId: string, snap: ContextSnapshot): void => {
193
- if (contextCache.has(sessionId)) contextCache.delete(sessionId);
194
- contextCache.set(sessionId, snap);
195
- if (contextCache.size > CONTEXT_CACHE_MAX) {
196
- const oldest = contextCache.keys().next().value;
197
- if (oldest !== undefined) contextCache.delete(oldest);
198
- }
199
- };
200
- const cacheGet = (sessionId: string): ContextSnapshot | undefined => {
201
- const snap = contextCache.get(sessionId);
202
- if (snap !== undefined) {
203
- contextCache.delete(sessionId);
204
- contextCache.set(sessionId, snap);
205
- }
206
- return snap;
207
- };
208
-
209
- const dispatch = async (effect: Effect): Promise<unknown> => {
210
- switch (effect.kind) {
211
- case 'read-context': {
212
- // Composite: assembles ContextSnapshot from scope + messages.
213
- // Each agent runtime still gets the same shape, but the backend has
214
- // no `/context/read` — assembly happens here, where the agent's
215
- // identity is in scope.
216
- const snap = await buildSnapshot(deps, effect.sessionId, deps.agentId, {
217
- limit: effect.opts?.maxMessages,
218
- });
219
- const me = (snap.agents as Array<{ isYou?: boolean; agentId?: string }>).find((a) => a?.isYou)?.agentId || null;
220
- outbox.merge(effect.sessionId, snap.history as Record<string, unknown>[], me);
221
- cachePut(effect.sessionId, snap);
222
- return snap;
223
- }
224
-
225
- case 'list-messages': {
226
- return deps.messagesClient.list(effect.chatId, {
227
- after: effect.after,
228
- limit: effect.limit,
229
- });
230
- }
231
-
232
- case 'list-artifacts': {
233
- return deps.artifactsClient.list(
234
- { chatId: effect.chatId, agreementId: effect.agreementId },
235
- { after: effect.after, limit: effect.limit },
236
- );
237
- }
238
-
239
- case 'list-task-history': {
240
- const url = new URL(
241
- `${process.env.ZIGGS_BACKEND_URL ?? 'http://localhost:3000'}/tasks/${effect.taskId}/history`,
242
- );
243
- if (effect.after) url.searchParams.set('after', effect.after);
244
- if (effect.limit != null) url.searchParams.set('limit', String(effect.limit));
245
- const res = await fetch(url.toString(), {
246
- headers: {
247
- 'content-type': 'application/json',
248
- Authorization: `Bearer ${deps.operatorKey}`,
249
- 'X-Agent-Id': deps.agentId,
250
- },
251
- });
252
- if (!res.ok) {
253
- throw new Error(`list-task-history ${res.status} ${res.statusText}`);
254
- }
255
- return res.json();
256
- }
257
-
258
- case 'get-scope': {
259
- return deps.scopeClient.get(effect.via.kind, effect.via.id);
260
- }
261
-
262
- case 'llm-call': {
263
- const t0 = Date.now();
264
- const r: LlmResponse = await deps.llm.chatMessages(effect.messages, effect.tools);
265
- sendTelemetry(
266
- deps.telemetryClient,
267
- buildLlmIngestPayload(r, {
268
- sessionId: effect.sessionId,
269
- durationMs: Date.now() - t0,
270
- runId: effect.runId,
271
- stateId: effect.stateId,
272
- }),
273
- isTelemetryIngestEnabled(deps.telemetryIngest),
274
- );
275
- return r;
276
- }
277
-
278
- case 'stream-text': {
279
- const { sessionId, receiverId, messageId, messages } = effect;
280
- let text = '';
281
- if (deps.llm.chatMessagesStream) {
282
- text = await deps.llm.chatMessagesStream(messages as LlmMessage[], (chunk) => {
283
- // Live-stream display is best-effort. The transport's send rejects
284
- // empty/whitespace-only content (WebSocketClient: content.trim() === ''),
285
- // and a whitespace-only chunk (e.g. a leading newline) is truthy yet
286
- // still throws — which, uncaught, aborts the whole stream and loses the
287
- // entire reply (e.g. a composer's final synthesis). Swallow chunk-send
288
- // failures; `text` accumulates independently and the final send-message
289
- // (below, in runTurn) carries the full reply regardless.
290
- try {
291
- if (chunk && chunk.trim()) deps.chunkSender?.(sessionId, receiverId, chunk, messageId);
292
- } catch { /* ignore — streaming display only */ }
293
- });
294
- } else {
295
- const r = await deps.llm.chatMessages(messages as LlmMessage[]);
296
- text = r.content ?? '';
297
- if (text) deps.chunkSender?.(sessionId, receiverId, text, messageId);
298
- }
299
- return { text };
300
- }
301
-
302
- case 'tool-call': {
303
- const toolT0 = Date.now();
304
- const cached = cacheGet(effect.sessionId);
305
- const agents = (cached?.agents as unknown[]) || [];
306
- const users = (cached?.users as unknown[]) || [];
307
- const args = (effect.args as Record<string, unknown>) || {};
308
- const argsPreview = previewToolArgs(args);
309
- await emitToolOperationArtifact(deps.artifactsClient, effect.sessionId, 'started', {
310
- state: 'started',
311
- tool: effect.name,
312
- ...(argsPreview ? { args: argsPreview } : {}),
313
- });
314
- try {
315
- const lastUser = (users as Array<{ userId?: string; id?: string }>).find(
316
- (u) => u.userId || u.id,
317
- );
318
- const result = await deps.toolManager.executeTool(
319
- effect.name,
320
- args,
321
- {
322
- operatorKey: deps.operatorKey,
323
- agentId: deps.agentId,
324
- chatId: effect.sessionId,
325
- taskService: deps.taskService,
326
- agreementService: deps.agreementService,
327
- sendMessage: deps.messageSender,
328
- agents,
329
- users,
330
- senderId: effect.senderId ?? lastUser?.userId ?? lastUser?.id,
331
- senderType: effect.senderType ?? (lastUser ? 'USER' : undefined),
332
- memory: effect.memory,
333
- turnScratch: {},
334
- },
335
- );
336
- await emitToolOperationArtifact(deps.artifactsClient, effect.sessionId, 'completed', {
337
- state: 'completed',
338
- tool: effect.name,
339
- result: clipForOperationArtifact(result),
340
- });
341
- sendTelemetry(
342
- deps.telemetryClient,
343
- buildToolIngestPayload({
344
- sessionId: effect.sessionId,
345
- tool: effect.name,
346
- durationMs: Date.now() - toolT0,
347
- ok: true,
348
- runId: effect.runId,
349
- stateId: effect.stateId,
350
- }),
351
- isTelemetryIngestEnabled(deps.telemetryIngest),
352
- );
353
- return { ok: true, result } satisfies ToolCallResult;
354
- } catch (error: unknown) {
355
- const errMsg = (error as Error)?.message ?? String(error);
356
- runtimeLog.warn('ZiggsEffectHandler', `tool-call "${effect.name}" failed: ${errMsg}`);
357
- await emitToolOperationArtifact(deps.artifactsClient, effect.sessionId, 'error', {
358
- state: 'failed',
359
- tool: effect.name,
360
- error: errMsg,
361
- });
362
- sendTelemetry(
363
- deps.telemetryClient,
364
- buildToolIngestPayload({
365
- sessionId: effect.sessionId,
366
- tool: effect.name,
367
- durationMs: Date.now() - toolT0,
368
- ok: false,
369
- runId: effect.runId,
370
- stateId: effect.stateId,
371
- }),
372
- isTelemetryIngestEnabled(deps.telemetryIngest),
373
- );
374
- return { ok: false, error: errMsg } satisfies ToolCallResult;
375
- }
376
- }
377
-
378
- case 'send-message': {
379
- await deps.messageSender(effect.text, effect.receiverId, effect.sessionId, effect.messageId);
380
- outbox.track(effect.sessionId, { text: effect.text, receiverId: effect.receiverId });
381
- return { ok: true };
382
- }
383
-
384
- case 'record-event': {
385
- // Routes through ArtifactsClient as an agent-private artifact —
386
- // visible to this agent across turns, not to other chat parties.
387
- try {
388
- if (effect.entry.kind === 'thought' && typeof effect.entry.text === 'string') {
389
- await deps.artifactsClient.recordThought(effect.sessionId, effect.entry.text);
390
- } else {
391
- await deps.artifactsClient.write({
392
- chatId: effect.sessionId,
393
- text: JSON.stringify(effect.entry),
394
- content_type: String(effect.entry.kind ?? 'event'),
395
- visibility: 'agent-private',
396
- });
397
- }
398
- } catch (err: unknown) {
399
- runtimeLog.warn('ZiggsEffectHandler', `record-event failed: ${(err as Error)?.message ?? String(err)}`);
400
- }
401
- return { ok: true };
402
- }
403
-
404
- default: {
405
- const exhaustive: never = effect;
406
- throw new Error(`ZiggsEffectHandler: unknown effect kind ${(exhaustive as Record<string, unknown>).kind}`);
407
- }
408
- }
409
- };
410
-
411
- const handler = async (effect: Effect): Promise<unknown> => {
412
- const response = await dispatch(effect);
413
- deps.effectTap?.(effect, response);
414
- return response;
415
- };
416
-
417
- return handler as EffectHandler;
418
- }
@@ -1,118 +0,0 @@
1
- import {
2
- proposeAgreement, proposeBroadcast as proposeBroadcastApi, delegateAgreement, respondToAgreement, counterAgreement,
3
- getAgreementStatus, listAgreements, getMyAgreements, getAgreement,
4
- publishOffer as publishOfferApi, createAgreement, revokeAgreement, getAgreementsByChat, linkAgreementToChat,
5
- getChatsForAgreement, joinAgreement, linkArtifactToAgreement, getArtifactsForAgreement,
6
- linkUserToAgreement, getUsersForAgreement,
7
- type Creds, type Agreement,
8
- type ProposeAgreementData, type ProposeDirectInput, type ProposeBroadcastInput,
9
- type PublishOfferPayload,
10
- type DelegateAgreementData, type CounterAgreementData,
11
- type CreateAgreementBody, type ListAgreementsFilters, type GetMyAgreementsFilters,
12
- type ChatLinkType, type ArtifactLinkType, type UserRole,
13
- } from '@ziggs-ai/api-client';
14
-
15
- export class AgreementService {
16
- private creds: Creds;
17
-
18
- constructor(operatorKey: string, agentId: string) {
19
- if (!operatorKey) throw new Error('AgreementService: operatorKey is required');
20
- if (!agentId) throw new Error('AgreementService: agentId is required (operator-token impersonation)');
21
- this.creds = { operatorKey, agentId };
22
- }
23
-
24
- /** 1:1 proposal. Server defaults engagementKind to `service` when omitted. */
25
- proposeDirect(payload: ProposeDirectInput): Promise<Agreement> {
26
- return proposeAgreement(payload, this.creds);
27
- }
28
-
29
- /**
30
- * Open buyer-broadcast. `payload.audience` selects who may see/claim it:
31
- * 'everyone' (default, fully public) or 'org' (members of your active org).
32
- * Server defaults engagementKind to `service`.
33
- */
34
- proposeBroadcast(payload: ProposeBroadcastInput): Promise<Agreement> {
35
- return proposeBroadcastApi(payload, this.creds);
36
- }
37
-
38
- /** @deprecated Alias for {@link proposeDirect}. */
39
- propose(payload: ProposeAgreementData): Promise<Agreement> {
40
- return proposeAgreement(payload, this.creds);
41
- }
42
-
43
- /**
44
- * Seller-broadcast marketplace offer. `payload.audience` sets the `payer`
45
- * sentinel: 'everyone' (default, public) or 'org' (your active org only).
46
- */
47
- publishOffer(payload: PublishOfferPayload): Promise<Agreement> {
48
- return publishOfferApi(payload, this.creds);
49
- }
50
-
51
- delegate(payload: DelegateAgreementData): Promise<Agreement> {
52
- return delegateAgreement(payload, this.creds);
53
- }
54
-
55
- respond(agreementId: string, action: 'approve' | 'reject'): Promise<Agreement> {
56
- return respondToAgreement(agreementId, action, this.creds);
57
- }
58
-
59
- counter(agreementId: string, counter: CounterAgreementData): Promise<Agreement> {
60
- return counterAgreement(agreementId, counter || {}, this.creds);
61
- }
62
-
63
- getStatus(agreementId: string): Promise<unknown | null> {
64
- return getAgreementStatus(agreementId, this.creds);
65
- }
66
-
67
- list(filters: ListAgreementsFilters = {}): Promise<Agreement[]> {
68
- return listAgreements(filters, this.creds);
69
- }
70
-
71
- mine(filters: GetMyAgreementsFilters = {}): Promise<Agreement[]> {
72
- return getMyAgreements(filters, this.creds);
73
- }
74
-
75
- get(agreementId: string): Promise<Agreement | null> {
76
- return getAgreement(agreementId, this.creds);
77
- }
78
-
79
- create(body: CreateAgreementBody): Promise<{ ok: boolean; agreement: Agreement }> {
80
- return createAgreement(body, this.creds);
81
- }
82
-
83
- revoke(agreementId: string): Promise<{ ok: boolean; agreement: Agreement }> {
84
- return revokeAgreement(agreementId, this.creds);
85
- }
86
-
87
- getByChat(chatId: string): Promise<unknown[]> {
88
- return getAgreementsByChat(chatId, this.creds);
89
- }
90
-
91
- linkToChat(agreementId: string, chatId: string, linkType: ChatLinkType = 'mention'): Promise<unknown | null> {
92
- return linkAgreementToChat(agreementId, chatId, linkType, this.creds);
93
- }
94
-
95
- getChats(agreementId: string): Promise<unknown[]> {
96
- return getChatsForAgreement(agreementId, this.creds);
97
- }
98
-
99
- join(agreementId: string): Promise<{ chatId: string; agentId: string | null; isNew: boolean }> {
100
- return joinAgreement(agreementId, this.creds);
101
- }
102
-
103
- linkArtifact(agreementId: string, artifactId: string, linkType: ArtifactLinkType = 'produced'): Promise<unknown | null> {
104
- return linkArtifactToAgreement(agreementId, artifactId, linkType, this.creds);
105
- }
106
-
107
- getArtifacts(agreementId: string): Promise<unknown[]> {
108
- return getArtifactsForAgreement(agreementId, this.creds);
109
- }
110
-
111
- linkUser(agreementId: string, userId: string, role: UserRole): Promise<unknown | null> {
112
- return linkUserToAgreement(agreementId, userId, role, this.creds);
113
- }
114
-
115
- getUsers(agreementId: string): Promise<unknown[]> {
116
- return getUsersForAgreement(agreementId, this.creds);
117
- }
118
- }
@@ -1,85 +0,0 @@
1
- import { createServer, type Server } from 'http';
2
- import type { ConnectionPool } from './ConnectionPool.js';
3
- import type { AgentHost } from '../AgentHost.js';
4
- import { runtimeLog } from '../shared/runtimeLog.js';
5
-
6
- function readJsonBody(req: import('http').IncomingMessage): Promise<Record<string, unknown>> {
7
- return new Promise((resolve, reject) => {
8
- const chunks: Buffer[] = [];
9
- req.on('data', (c) => chunks.push(c));
10
- req.on('end', () => {
11
- try {
12
- const raw = Buffer.concat(chunks).toString('utf8');
13
- resolve(raw ? (JSON.parse(raw) as Record<string, unknown>) : {});
14
- } catch (err) {
15
- reject(err);
16
- }
17
- });
18
- req.on('error', reject);
19
- });
20
- }
21
-
22
- export function createHealthServer({
23
- port = Number(process.env.PORT) || 8080,
24
- label = 'agents',
25
- pool,
26
- }: {
27
- port?: number;
28
- label?: string;
29
- pool?: ConnectionPool;
30
- } = {}): Server {
31
- const server = createServer(async (req, res) => {
32
- const url = req.url ?? '/';
33
- const wakeMatch = url.match(/^\/fleet-wake\/([^/?]+)/);
34
- if (req.method === 'POST' && wakeMatch && pool) {
35
- const agentId = decodeURIComponent(wakeMatch[1]);
36
- try {
37
- await pool.wake(agentId);
38
- res.writeHead(200, { 'Content-Type': 'application/json' });
39
- res.end(JSON.stringify({ ok: true, agentId, active: pool.listActive().includes(agentId) }));
40
- } catch (err) {
41
- res.writeHead(500, { 'Content-Type': 'application/json' });
42
- res.end(JSON.stringify({ ok: false, error: (err as Error).message }));
43
- }
44
- return;
45
- }
46
-
47
- if (req.method === 'POST' && url === '/fleet-deliver' && pool) {
48
- try {
49
- const body = await readJsonBody(req);
50
- const agentId = String(body.agentId ?? '');
51
- const chatId = String(body.chatId ?? '');
52
- const text = String(body.text ?? '');
53
- const senderId = String(body.senderId ?? '');
54
- if (!agentId || !chatId || !text || !senderId) {
55
- res.writeHead(400, { 'Content-Type': 'application/json' });
56
- res.end(JSON.stringify({ ok: false, error: 'agentId, chatId, text, senderId required' }));
57
- return;
58
- }
59
- const host = (await pool.wake(agentId)) as AgentHost;
60
- await host.handleMessage(text, {
61
- chatId,
62
- entryType: 'message',
63
- content_type: 'text',
64
- sender: { id: senderId, type: 'USER' },
65
- receiver: { id: agentId, type: 'AGENT' },
66
- });
67
- res.writeHead(200, { 'Content-Type': 'application/json' });
68
- res.end(JSON.stringify({ ok: true, agentId }));
69
- } catch (err) {
70
- res.writeHead(500, { 'Content-Type': 'application/json' });
71
- res.end(JSON.stringify({ ok: false, error: (err as Error).message }));
72
- }
73
- return;
74
- }
75
- if (url === '/health' || url === '/') {
76
- res.writeHead(200);
77
- res.end('ok');
78
- return;
79
- }
80
- res.writeHead(404);
81
- res.end();
82
- });
83
- server.listen(port, () => runtimeLog.info(label, `health server on port ${port}`));
84
- return server;
85
- }