@ziggs-ai/agent-sdk 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +9 -4
- package/src/AgentHost.ts +342 -0
- package/src/adapters/OpenAIAdapter.ts +125 -0
- package/src/agent/Agent.ts +98 -0
- package/src/cognition/validateContext.ts +95 -0
- package/src/context/applyEffects.ts +80 -0
- package/src/context/batch.ts +17 -0
- package/src/context/classifyEnvelope.ts +38 -0
- package/src/context/routingLabels.ts +46 -0
- package/src/defineAgent.ts +62 -0
- package/src/formatters/AgreementFormatter.ts +111 -0
- package/src/formatters/HistoryFormatter.ts +166 -0
- package/src/formatters/index.ts +2 -0
- package/src/index.ts +86 -0
- package/src/ingress/normalizeIncoming.ts +119 -0
- package/src/memory/MemoryStore.ts +104 -0
- package/src/runtime/AgentMachine.ts +298 -0
- package/src/runtime/PromptBuilder.ts +461 -0
- package/src/runtime/buildOutcome.ts +488 -0
- package/src/runtime/defaults.ts +72 -0
- package/src/runtime/runTurn.ts +637 -0
- package/src/runtime/validateWorkflow.ts +165 -0
- package/src/server/ConnectionPool.ts +155 -0
- package/src/server/EventQueue.ts +119 -0
- package/src/server/OutboxBuffer.ts +90 -0
- package/src/server/ZiggsEffectHandler.ts +335 -0
- package/src/server/agreements/AgreementService.ts +111 -0
- package/src/server/createHealthServer.ts +8 -0
- package/src/server/proactive/ProactiveTrigger.ts +83 -0
- package/src/server/runLauncher.ts +131 -0
- package/src/server/tasks/TaskService.ts +111 -0
- package/src/server/tasks/index.ts +4 -0
- package/src/server/tasks/paymentTools.ts +156 -0
- package/src/server/tasks/protocolRunner.ts +101 -0
- package/src/server/tasks/protocolTools.ts +96 -0
- package/src/server/ziggspay/ZiggsPayClient.ts +193 -0
- package/src/shared/ids.ts +3 -0
- package/src/shared/runtimeLog.ts +72 -0
- package/src/shared/types.ts +31 -0
- package/src/tasks/protocolRegistry.ts +25 -0
- package/src/tasks/taskCore.ts +139 -0
- package/src/tools/ToolManager.ts +95 -0
- package/src/tools/{ToolProvider.js → ToolProvider.ts} +5 -15
- package/src/tools/defineTool.ts +90 -0
- package/src/tools/index.ts +5 -0
- package/src/types.ts +368 -0
- package/src/utils/jsonExtractor.ts +100 -0
- package/src/ConnectionPool.js +0 -133
- package/src/adapters/OpenAIAdapter.js +0 -73
- package/src/agent/Agent.js +0 -121
- package/src/agent/EventQueue.js +0 -68
- package/src/agent/OutboxBuffer.js +0 -62
- package/src/cognition/PromptBuilder.js +0 -312
- package/src/cognition/resolveActionTool.js +0 -12
- package/src/cognition/runTurn.js +0 -578
- package/src/context/applyEffects.js +0 -133
- package/src/context/batch.js +0 -25
- package/src/context/classifyEnvelope.js +0 -82
- package/src/context/routingLabels.js +0 -54
- package/src/createHealthServer.js +0 -28
- package/src/formatters/HistoryFormatter.js +0 -257
- package/src/formatters/TaskFormatter.js +0 -180
- package/src/formatters/index.js +0 -9
- package/src/index.js +0 -76
- package/src/ingress/normalizeIncoming.js +0 -70
- package/src/runLauncher.js +0 -159
- package/src/shared/ids.js +0 -7
- package/src/shared/types.js +0 -86
- package/src/tasks/TaskService.js +0 -247
- package/src/tasks/index.js +0 -9
- package/src/tasks/taskCore.js +0 -229
- package/src/tasks/taskProtocolRegistry.js +0 -22
- package/src/tasks/taskProtocolRunner.js +0 -107
- package/src/tasks/taskProtocolTools.js +0 -87
- package/src/tools/ToolManager.js +0 -79
- package/src/tools/defineTool.js +0 -82
- package/src/tools/index.js +0 -11
- package/src/utils/jsonExtractor.js +0 -139
- package/src/workflow/AgentMachine.js +0 -250
- package/src/workflow/WorkflowRuntime.js +0 -63
- package/src/workflow/dsl.js +0 -287
- package/src/workflow/motifs.js +0 -435
- package/src/ziggs/runtime.js +0 -192
- /package/src/adapters/{index.js → index.ts} +0 -0
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { AgentMachine } from './AgentMachine.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* One AgentMachine per lane; dispatches events and waits until parked.
|
|
5
|
-
*/
|
|
6
|
-
export class WorkflowRuntime {
|
|
7
|
-
constructor({ definition, executionCore, services, onSnapshot }) {
|
|
8
|
-
this.definition = definition;
|
|
9
|
-
this.executionCore = executionCore;
|
|
10
|
-
this.services = services;
|
|
11
|
-
this.onSnapshot = onSnapshot;
|
|
12
|
-
this.actors = new Map();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
getOrCreate(laneKey, input = {}) {
|
|
16
|
-
let machine = this.actors.get(laneKey);
|
|
17
|
-
if (machine && machine.status === 'active') return machine;
|
|
18
|
-
|
|
19
|
-
machine = new AgentMachine({
|
|
20
|
-
definition: this.definition,
|
|
21
|
-
executionCore: this.executionCore,
|
|
22
|
-
services: this.services,
|
|
23
|
-
input,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
if (this.onSnapshot) {
|
|
27
|
-
machine.subscribe(snapshot => {
|
|
28
|
-
console.log(`[${this.definition.id || 'agent'}] → ${JSON.stringify(snapshot.value)}`);
|
|
29
|
-
this.onSnapshot(laneKey, snapshot);
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
this.actors.set(laneKey, machine);
|
|
34
|
-
return machine;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async sendAndWaitForPark({ laneKey, event, timeoutMs = 120_000, machineInput = {} }) {
|
|
38
|
-
const machine = this.getOrCreate(laneKey, machineInput);
|
|
39
|
-
|
|
40
|
-
return new Promise(resolve => {
|
|
41
|
-
let settled = false;
|
|
42
|
-
|
|
43
|
-
const settle = () => {
|
|
44
|
-
if (settled) return;
|
|
45
|
-
settled = true;
|
|
46
|
-
clearTimeout(timer);
|
|
47
|
-
sub.unsubscribe();
|
|
48
|
-
resolve();
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const sub = machine.subscribe(() => {
|
|
52
|
-
if (machine.isParked) settle();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
machine.send(event);
|
|
56
|
-
|
|
57
|
-
const timer = setTimeout(() => {
|
|
58
|
-
console.warn(`[WorkflowRuntime] Timed out after ${timeoutMs}ms laneKey=${laneKey}`);
|
|
59
|
-
settle();
|
|
60
|
-
}, timeoutMs);
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
package/src/workflow/dsl.js
DELETED
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ziggs Agent DSL
|
|
3
|
-
*
|
|
4
|
-
* A small, indentation-based language for describing agents. Parsed at
|
|
5
|
-
* import time into a defineAgent-ready config. No state names, no
|
|
6
|
-
* transitions, no ctx flags — just the agent's intent.
|
|
7
|
-
*
|
|
8
|
-
* import { agent } from '@ziggs-ai/agent-sdk/dsl';
|
|
9
|
-
*
|
|
10
|
-
* export default agent`
|
|
11
|
-
* id weather-forecaster
|
|
12
|
-
* role Weather Forecaster
|
|
13
|
-
* goal Deliver real-time forecasts using live APIs
|
|
14
|
-
* tools weather-forecast
|
|
15
|
-
*
|
|
16
|
-
* behavior service
|
|
17
|
-
* ask when details are missing
|
|
18
|
-
* report before closing the task
|
|
19
|
-
* `;
|
|
20
|
-
*
|
|
21
|
-
* Grammar (indentation-sensitive, 2-space blocks):
|
|
22
|
-
*
|
|
23
|
-
* <program> ::= <header>* <behavior-block>
|
|
24
|
-
* <header> ::= <key> <value>\n
|
|
25
|
-
* <behavior> ::= "behavior" <shape> [<arg>]\n <option>*
|
|
26
|
-
* <option> ::= <indent> <key> <value>\n
|
|
27
|
-
*
|
|
28
|
-
* <shape> ::= "service" | "pipeline" | "map-reduce"
|
|
29
|
-
* | "debate" | "voting" | "critic" | "hierarchical"
|
|
30
|
-
* | "compose"
|
|
31
|
-
* <arg> ::= "of" <int> ("steps"|"rounds"|"chunks"|"voters")
|
|
32
|
-
*
|
|
33
|
-
* Unknown keys and misaligned indentation throw at parse time.
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
import { defineAgent } from '../ziggs/runtime.js';
|
|
37
|
-
import {
|
|
38
|
-
listen, propose, execute,
|
|
39
|
-
plan, dispatch, awaitSubtasks, synthesize,
|
|
40
|
-
seq, loop, compile, service as serviceFrag,
|
|
41
|
-
} from './motifs.js';
|
|
42
|
-
|
|
43
|
-
// ── Tokenizer ─────────────────────────────────────────────────────────────
|
|
44
|
-
|
|
45
|
-
function dedent(src) {
|
|
46
|
-
const lines = src.split('\n');
|
|
47
|
-
// Drop leading/trailing blank lines
|
|
48
|
-
while (lines.length && !lines[0].trim()) lines.shift();
|
|
49
|
-
while (lines.length && !lines[lines.length - 1].trim()) lines.pop();
|
|
50
|
-
const indents = lines
|
|
51
|
-
.filter(l => l.trim())
|
|
52
|
-
.map(l => l.match(/^ */)[0].length);
|
|
53
|
-
const base = Math.min(...indents, Infinity);
|
|
54
|
-
return lines.map(l => l.slice(base));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function tokenize(src) {
|
|
58
|
-
const lines = dedent(src);
|
|
59
|
-
const tokens = [];
|
|
60
|
-
for (let i = 0; i < lines.length; i++) {
|
|
61
|
-
const raw = lines[i];
|
|
62
|
-
if (!raw.trim()) { tokens.push({ kind: 'blank', line: i + 1 }); continue; }
|
|
63
|
-
const indent = raw.match(/^ */)[0].length;
|
|
64
|
-
if (indent % 2 !== 0) {
|
|
65
|
-
throw new SyntaxError(`line ${i + 1}: indent must be a multiple of 2 spaces`);
|
|
66
|
-
}
|
|
67
|
-
const text = raw.trim();
|
|
68
|
-
// Split on first run of 2+ spaces OR a single space if key is one word.
|
|
69
|
-
const m = text.match(/^([\w-]+)\s+(.*)$/);
|
|
70
|
-
if (!m) {
|
|
71
|
-
tokens.push({ kind: 'flag', key: text, line: i + 1, depth: indent / 2 });
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
tokens.push({
|
|
75
|
-
kind: 'pair',
|
|
76
|
-
key: m[1].toLowerCase(),
|
|
77
|
-
value: m[2].trim(),
|
|
78
|
-
depth: indent / 2,
|
|
79
|
-
line: i + 1,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
return tokens;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// ── Parser ────────────────────────────────────────────────────────────────
|
|
86
|
-
|
|
87
|
-
const HEADER_KEYS = new Set(['id', 'role', 'goal', 'context', 'constraints', 'tools', 'model']);
|
|
88
|
-
const SHAPES = new Set([
|
|
89
|
-
'service', 'pipeline', 'map-reduce', 'debate',
|
|
90
|
-
'voting', 'critic', 'hierarchical', 'compose',
|
|
91
|
-
]);
|
|
92
|
-
const ARG_WORDS = { steps: 'count', rounds: 'count', chunks: 'count', voters: 'count' };
|
|
93
|
-
|
|
94
|
-
function parse(tokens) {
|
|
95
|
-
const config = { headers: {}, behavior: null };
|
|
96
|
-
let i = 0;
|
|
97
|
-
|
|
98
|
-
// Headers (depth 0 key/value pairs before behavior)
|
|
99
|
-
while (i < tokens.length) {
|
|
100
|
-
const t = tokens[i];
|
|
101
|
-
if (t.kind === 'blank') { i++; continue; }
|
|
102
|
-
if (t.kind !== 'pair' || t.depth !== 0) break;
|
|
103
|
-
if (t.key === 'behavior') break;
|
|
104
|
-
if (!HEADER_KEYS.has(t.key)) {
|
|
105
|
-
throw new SyntaxError(`line ${t.line}: unknown header "${t.key}". Valid: ${[...HEADER_KEYS].join(', ')}`);
|
|
106
|
-
}
|
|
107
|
-
config.headers[t.key] = t.value;
|
|
108
|
-
i++;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Behavior block
|
|
112
|
-
const bt = tokens[i];
|
|
113
|
-
if (!bt || bt.key !== 'behavior') {
|
|
114
|
-
throw new SyntaxError('missing "behavior" block');
|
|
115
|
-
}
|
|
116
|
-
config.behavior = parseBehavior(bt, tokens, i);
|
|
117
|
-
return config;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function parseBehavior(header, tokens, start) {
|
|
121
|
-
// behavior pipeline of 5 steps
|
|
122
|
-
// option value
|
|
123
|
-
// option value
|
|
124
|
-
const parts = header.value.split(/\s+/);
|
|
125
|
-
const shape = parts[0];
|
|
126
|
-
if (!SHAPES.has(shape)) {
|
|
127
|
-
throw new SyntaxError(`line ${header.line}: unknown shape "${shape}". Valid: ${[...SHAPES].join(', ')}`);
|
|
128
|
-
}
|
|
129
|
-
const behavior = { shape, options: {} };
|
|
130
|
-
|
|
131
|
-
// Optional "of N <word>" suffix
|
|
132
|
-
if (parts[1] === 'of') {
|
|
133
|
-
const n = parseInt(parts[2], 10);
|
|
134
|
-
const word = parts[3];
|
|
135
|
-
if (isNaN(n) || !word || !(word in ARG_WORDS)) {
|
|
136
|
-
throw new SyntaxError(`line ${header.line}: expected "of <n> (steps|rounds|chunks|voters)"`);
|
|
137
|
-
}
|
|
138
|
-
behavior.options[ARG_WORDS[word]] = n;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Indented options
|
|
142
|
-
let i = start + 1;
|
|
143
|
-
while (i < tokens.length) {
|
|
144
|
-
const t = tokens[i];
|
|
145
|
-
if (t.kind === 'blank') { i++; continue; }
|
|
146
|
-
if (t.depth !== 1) break;
|
|
147
|
-
if (t.kind === 'pair') {
|
|
148
|
-
behavior.options[t.key] = t.value;
|
|
149
|
-
} else {
|
|
150
|
-
behavior.options[t.key] = true;
|
|
151
|
-
}
|
|
152
|
-
i++;
|
|
153
|
-
}
|
|
154
|
-
return behavior;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// ── Compiler (DSL → motif fragments → defineAgent config) ────────────────
|
|
158
|
-
|
|
159
|
-
function compileService({ tool, work, ...rest }, headers) {
|
|
160
|
-
return serviceFrag({
|
|
161
|
-
role: headers.role,
|
|
162
|
-
goal: headers.goal,
|
|
163
|
-
context: headers.context,
|
|
164
|
-
constraints: headers.constraints,
|
|
165
|
-
toolHint: tool || (headers.tools?.split(',')[0]?.trim()),
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function compilePipeline(opts, headers) {
|
|
170
|
-
return seq(
|
|
171
|
-
plan({ role: headers.role, goal: headers.goal, maxItems: opts.count ?? 5 }),
|
|
172
|
-
dispatch({ parallel: false }),
|
|
173
|
-
awaitSubtasks({ mode: 'one', name: 'awaitingStep' }),
|
|
174
|
-
synthesize({ role: headers.role }),
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
function compileMapReduce(opts, headers) {
|
|
179
|
-
return seq(
|
|
180
|
-
plan({ role: headers.role, maxItems: opts.count ?? 8, name: 'splitting' }),
|
|
181
|
-
dispatch({ parallel: true }),
|
|
182
|
-
awaitSubtasks({ mode: 'all', name: 'awaitingChunks' }),
|
|
183
|
-
synthesize({ role: headers.role, name: 'reducing' }),
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
function compileDebate(opts, headers) {
|
|
188
|
-
const rounds = opts.count ?? 3;
|
|
189
|
-
return seq(
|
|
190
|
-
plan({ role: headers.role, maxItems: 4 }),
|
|
191
|
-
loop(rounds,
|
|
192
|
-
dispatch({ parallel: true, name: 'round' }),
|
|
193
|
-
awaitSubtasks({ mode: 'all', name: 'collecting' }),
|
|
194
|
-
),
|
|
195
|
-
synthesize({ role: headers.role, name: 'concluding' }),
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function compileVoting(opts, headers) {
|
|
200
|
-
return seq(
|
|
201
|
-
plan({ role: headers.role, maxItems: opts.count ?? 5 }),
|
|
202
|
-
dispatch({ parallel: true, name: 'polling' }),
|
|
203
|
-
awaitSubtasks({ mode: 'all', name: 'counting' }),
|
|
204
|
-
synthesize({ role: headers.role, name: 'deciding', goal: 'Tally votes and announce the decision.' }),
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
function compileCritic(opts, headers) {
|
|
209
|
-
const rounds = opts.count ?? 2;
|
|
210
|
-
return seq(
|
|
211
|
-
plan({ role: headers.role, maxItems: 2 }),
|
|
212
|
-
loop(rounds,
|
|
213
|
-
dispatch({ parallel: false, name: 'drafting' }),
|
|
214
|
-
awaitSubtasks({ mode: 'one', name: 'reviewing' }),
|
|
215
|
-
),
|
|
216
|
-
synthesize({ role: headers.role }),
|
|
217
|
-
);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
function compileHierarchical(opts, headers) {
|
|
221
|
-
return seq(
|
|
222
|
-
plan({ role: headers.role, maxItems: opts.count ?? 5, goal: 'Choose lieutenants and assign sub-goals.' }),
|
|
223
|
-
dispatch({ parallel: true, name: 'delegating' }),
|
|
224
|
-
awaitSubtasks({ mode: 'all', name: 'awaitingReports' }),
|
|
225
|
-
synthesize({ role: headers.role }),
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const SHAPE_COMPILERS = {
|
|
230
|
-
service: compileService,
|
|
231
|
-
pipeline: compilePipeline,
|
|
232
|
-
'map-reduce': compileMapReduce,
|
|
233
|
-
debate: compileDebate,
|
|
234
|
-
voting: compileVoting,
|
|
235
|
-
critic: compileCritic,
|
|
236
|
-
hierarchical: compileHierarchical,
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
// ── Public API: tagged template ───────────────────────────────────────────
|
|
240
|
-
|
|
241
|
-
const EXPR_TOKEN = (i) => `__EXPR_${i}__`;
|
|
242
|
-
|
|
243
|
-
export function agent(strings, ...exprs) {
|
|
244
|
-
// Inline each interpolation as a stable placeholder so we can look up the
|
|
245
|
-
// real JS value (e.g. a defineTool instance) after text parsing.
|
|
246
|
-
let src = strings[0];
|
|
247
|
-
for (let i = 0; i < exprs.length; i++) src += EXPR_TOKEN(i) + strings[i + 1];
|
|
248
|
-
|
|
249
|
-
const tokens = tokenize(src);
|
|
250
|
-
const { headers, behavior } = parse(tokens);
|
|
251
|
-
|
|
252
|
-
// Resolve interpolated tool references.
|
|
253
|
-
const rawTools = (headers.tools ?? '').split(',').map(s => s.trim()).filter(Boolean);
|
|
254
|
-
headers.__tools = rawTools.map(ref => {
|
|
255
|
-
const m = ref.match(/^__EXPR_(\d+)__$/);
|
|
256
|
-
return m ? exprs[+m[1]] : ref;
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
if (!headers.id) throw new SyntaxError('missing required header "id"');
|
|
260
|
-
if (!headers.role) throw new SyntaxError('missing required header "role"');
|
|
261
|
-
|
|
262
|
-
const compiler = SHAPE_COMPILERS[behavior.shape];
|
|
263
|
-
const fragment = compiler(behavior.options, headers);
|
|
264
|
-
const { initial, states } = compile(fragment);
|
|
265
|
-
|
|
266
|
-
// Tools come from interpolation (${toolInstance}) — any non-string value in
|
|
267
|
-
// the tools header is a real defineTool() instance. String values are
|
|
268
|
-
// unresolved names and are dropped here (service agents that need a tool
|
|
269
|
-
// must interpolate it).
|
|
270
|
-
const tools = (headers.__tools ?? []).filter(t => t && typeof t === 'object');
|
|
271
|
-
|
|
272
|
-
return defineAgent({
|
|
273
|
-
agentId: headers.id,
|
|
274
|
-
description: headers.role,
|
|
275
|
-
specialization: headers.goal,
|
|
276
|
-
initial,
|
|
277
|
-
states,
|
|
278
|
-
tools,
|
|
279
|
-
...(headers.model && { services: { llm: { model: headers.model } } }),
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// Escape hatch: parse without compiling, for testing/tooling.
|
|
284
|
-
export function parseDsl(strings, ...exprs) {
|
|
285
|
-
const src = Array.isArray(strings) ? String.raw({ raw: strings }, ...exprs) : strings;
|
|
286
|
-
return parse(tokenize(src));
|
|
287
|
-
}
|