@noetic-tools/core 0.3.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/harness/agent-harness.d.ts +2 -2
- package/dist/harness/agent-harness.js +17 -5
- package/dist/harness/model-call.js +9 -8
- package/dist/harness/model-schema.d.ts +8 -0
- package/dist/harness/model-schema.js +8 -0
- package/dist/index.d.ts +1 -1
- package/dist/interpreter/execute-action.js +19 -2
- package/dist/interpreter/execute-control.js +59 -4
- package/dist/runtime/channel-store.d.ts +42 -2
- package/dist/runtime/channel-store.js +232 -35
- package/dist/runtime/context-impl.d.ts +17 -1
- package/dist/runtime/context-impl.js +30 -3
- package/dist/runtime/durable/stall-nudge.d.ts +16 -9
- package/dist/runtime/durable/stall-nudge.js +29 -10
- package/dist/runtime/event-broadcaster.d.ts +9 -1
- package/dist/runtime/event-broadcaster.js +43 -19
- package/dist/schemas/workflow.js +21 -5
- package/package.json +7 -4
- package/schema/noetic-workflow.schema.json +523 -0
|
@@ -101,7 +101,13 @@ export class EventBroadcaster {
|
|
|
101
101
|
//#region BroadcastIterator
|
|
102
102
|
class BroadcastIterator {
|
|
103
103
|
cursor = 0;
|
|
104
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Parked `next()` calls, FIFO. The AsyncIterator protocol allows pipelined
|
|
106
|
+
* `next()` calls (calling again before the previous promise settles), so a
|
|
107
|
+
* single waiter slot would orphan all but the latest call — the overwritten
|
|
108
|
+
* promises would never settle. `notify()` drains in arrival order.
|
|
109
|
+
*/
|
|
110
|
+
waiters = [];
|
|
105
111
|
returned = false;
|
|
106
112
|
broadcaster;
|
|
107
113
|
constructor(broadcaster) {
|
|
@@ -113,20 +119,22 @@ class BroadcastIterator {
|
|
|
113
119
|
}
|
|
114
120
|
/** Called by the broadcaster when new data or completion is available. */
|
|
115
121
|
notify() {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
this.waiter = undefined;
|
|
121
|
-
try {
|
|
122
|
-
const result = this.tryRead();
|
|
123
|
-
if (result) {
|
|
124
|
-
w.resolve(result);
|
|
122
|
+
while (this.waiters.length > 0) {
|
|
123
|
+
let result;
|
|
124
|
+
try {
|
|
125
|
+
result = this.tryRead();
|
|
125
126
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
catch (err) {
|
|
128
|
+
// Reject so the error propagates through the async iterator. The
|
|
129
|
+
// broadcaster stays finished-with-error, so the loop drains every
|
|
130
|
+
// remaining waiter with the same rejection.
|
|
131
|
+
this.waiters.shift().reject(err);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (!result) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
this.waiters.shift().resolve(result);
|
|
130
138
|
}
|
|
131
139
|
}
|
|
132
140
|
async next() {
|
|
@@ -136,25 +144,41 @@ class BroadcastIterator {
|
|
|
136
144
|
value: undefined,
|
|
137
145
|
};
|
|
138
146
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
147
|
+
// Only read ahead when no one is parked — a pipelined next() must queue
|
|
148
|
+
// BEHIND earlier calls so events are handed out in FIFO order.
|
|
149
|
+
if (this.waiters.length === 0) {
|
|
150
|
+
const result = this.tryRead();
|
|
151
|
+
if (result) {
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
142
154
|
}
|
|
143
155
|
return new Promise((resolve, reject) => {
|
|
144
|
-
this.
|
|
156
|
+
this.waiters.push({
|
|
145
157
|
resolve,
|
|
146
158
|
reject,
|
|
147
|
-
};
|
|
159
|
+
});
|
|
148
160
|
});
|
|
149
161
|
}
|
|
162
|
+
/** Settle every parked waiter with `{ done: true }` — used on early exit. */
|
|
163
|
+
settleWaiters() {
|
|
164
|
+
const drained = this.waiters.splice(0, this.waiters.length);
|
|
165
|
+
for (const waiter of drained) {
|
|
166
|
+
waiter.resolve({
|
|
167
|
+
done: true,
|
|
168
|
+
value: undefined,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
150
172
|
async throw(err) {
|
|
151
173
|
this.returned = true;
|
|
152
174
|
this.broadcaster.removeIterator(this);
|
|
175
|
+
this.settleWaiters();
|
|
153
176
|
throw err;
|
|
154
177
|
}
|
|
155
178
|
async return() {
|
|
156
179
|
this.returned = true;
|
|
157
180
|
this.broadcaster.removeIterator(this);
|
|
181
|
+
this.settleWaiters();
|
|
158
182
|
return {
|
|
159
183
|
done: true,
|
|
160
184
|
value: undefined,
|
package/dist/schemas/workflow.js
CHANGED
|
@@ -46,7 +46,8 @@ const AllPredicateSchema = z.object({
|
|
|
46
46
|
predicates: z.array(UntilPredicateRef).min(1),
|
|
47
47
|
});
|
|
48
48
|
/** @public Zod schema validating a named `until` predicate (including `any`/`all` combinators). */
|
|
49
|
-
export const UntilPredicateSchema = z
|
|
49
|
+
export const UntilPredicateSchema = z
|
|
50
|
+
.union([
|
|
50
51
|
MaxStepsPredicateSchema,
|
|
51
52
|
MaxCostPredicateSchema,
|
|
52
53
|
MaxDurationPredicateSchema,
|
|
@@ -56,7 +57,11 @@ export const UntilPredicateSchema = z.union([
|
|
|
56
57
|
ConvergedPredicateSchema,
|
|
57
58
|
AnyPredicateSchema,
|
|
58
59
|
AllPredicateSchema,
|
|
59
|
-
])
|
|
60
|
+
])
|
|
61
|
+
.meta({
|
|
62
|
+
id: 'UntilPredicate',
|
|
63
|
+
title: 'UntilPredicate',
|
|
64
|
+
});
|
|
60
65
|
//#endregion
|
|
61
66
|
//#region Merge Strategy
|
|
62
67
|
/** @public ESM literal enum for merge strategies. */
|
|
@@ -158,7 +163,8 @@ const EveryNodeSchema = z.object({
|
|
|
158
163
|
.optional(),
|
|
159
164
|
});
|
|
160
165
|
/** @public Zod schema validating a single `WorkflowNode` (any of the 9 JSON-safe kinds). */
|
|
161
|
-
export const WorkflowNodeSchema = z
|
|
166
|
+
export const WorkflowNodeSchema = z
|
|
167
|
+
.discriminatedUnion('kind', [
|
|
162
168
|
LlmNodeSchema,
|
|
163
169
|
ToolNodeSchema,
|
|
164
170
|
BranchNodeSchema,
|
|
@@ -168,11 +174,21 @@ export const WorkflowNodeSchema = z.discriminatedUnion('kind', [
|
|
|
168
174
|
LoopNodeSchema,
|
|
169
175
|
SequenceNodeSchema,
|
|
170
176
|
EveryNodeSchema,
|
|
171
|
-
])
|
|
177
|
+
])
|
|
178
|
+
.meta({
|
|
179
|
+
id: 'WorkflowNode',
|
|
180
|
+
title: 'WorkflowNode',
|
|
181
|
+
});
|
|
172
182
|
/** @public Zod schema validating a complete `WorkflowDocument`. */
|
|
173
|
-
export const WorkflowDocumentSchema = z
|
|
183
|
+
export const WorkflowDocumentSchema = z
|
|
184
|
+
.object({
|
|
174
185
|
version: z.literal(1),
|
|
175
186
|
root: WorkflowNodeSchema,
|
|
187
|
+
})
|
|
188
|
+
.meta({
|
|
189
|
+
id: 'WorkflowDocument',
|
|
190
|
+
title: 'WorkflowDocument',
|
|
191
|
+
description: 'A portable, JSON-safe representation of a Noetic step tree.',
|
|
176
192
|
});
|
|
177
193
|
//#endregion
|
|
178
194
|
//#region Helpers
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noetic-tools/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Step primitives, interpreter, runtime, and memory layer contract for Noetic agents.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -40,10 +40,12 @@
|
|
|
40
40
|
"types": "./dist/internal-test.d.ts",
|
|
41
41
|
"default": "./dist/internal-test.js"
|
|
42
42
|
},
|
|
43
|
+
"./schema": "./schema/noetic-workflow.schema.json",
|
|
43
44
|
"./package.json": "./package.json"
|
|
44
45
|
},
|
|
45
46
|
"files": [
|
|
46
47
|
"dist",
|
|
48
|
+
"schema",
|
|
47
49
|
"README.md",
|
|
48
50
|
"LICENSE"
|
|
49
51
|
],
|
|
@@ -64,15 +66,16 @@
|
|
|
64
66
|
}
|
|
65
67
|
},
|
|
66
68
|
"dependencies": {
|
|
67
|
-
"@noetic-tools/memory": "^0.
|
|
68
|
-
"@noetic-tools/types": "^0.
|
|
69
|
+
"@noetic-tools/memory": "^1.0.1",
|
|
70
|
+
"@noetic-tools/types": "^1.0.0",
|
|
69
71
|
"@openrouter/agent": "^0.6.0",
|
|
70
72
|
"zod": "^4.0.0"
|
|
71
73
|
},
|
|
72
74
|
"scripts": {
|
|
73
75
|
"build": "bunx tsc -p tsconfig.build.json && bun scripts/add-js-extensions.ts",
|
|
76
|
+
"gen:schema": "bun scripts/generate-workflow-schema.ts",
|
|
74
77
|
"verify:esm": "bun scripts/verify-node-esm.ts",
|
|
75
|
-
"prepublishOnly": "rm -rf dist && bun run build && bun run verify:esm && bun scripts/pin-workspace-deps.ts",
|
|
78
|
+
"prepublishOnly": "rm -rf dist && bun run gen:schema && bun run build && bun run verify:esm && bun scripts/pin-workspace-deps.ts && bun scripts/strip-dev-conditions.ts",
|
|
76
79
|
"test": "bun test",
|
|
77
80
|
"test:coverage": "bun test --coverage --coverage-reporter=text --coverage-reporter=lcov",
|
|
78
81
|
"test:ci": "bun test --coverage --coverage-reporter=lcov",
|