dsh-lcx-codex 0.4.3-pre.4 → 0.4.3

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 (42) hide show
  1. package/README.md +68 -126
  2. package/THIRD_PARTY_NOTICES.md +64 -0
  3. package/lib/auxiliary-usage.js +63 -0
  4. package/lib/client.js +1363 -295
  5. package/lib/dsh-compat.js +80 -18
  6. package/lib/dsh-responses.js +75 -8
  7. package/lib/grok-native-search.js +151 -79
  8. package/lib/index.js +159 -101
  9. package/lib/invocation-policy-scope.js +261 -0
  10. package/lib/json-store.js +11 -4
  11. package/lib/pi-responses-runtime.js +1571 -0
  12. package/lib/responses-request.js +1 -1
  13. package/lib/responses-stream.js +152 -84
  14. package/lib/route.js +17 -3
  15. package/lib/search-accounting.js +86 -0
  16. package/lib/search-usage.js +86 -0
  17. package/lib/transport.js +38 -10
  18. package/lib/types/client/index.d.ts +12 -0
  19. package/lib/types/client/search-media.d.ts +16 -0
  20. package/lib/web-run-output.js +22 -0
  21. package/lib/web-search-alpha.js +230 -28
  22. package/lib/web-search-capability.js +26 -1
  23. package/lib/web-search-hosted.js +119 -9
  24. package/lib/web-search-ref-store.js +88 -7
  25. package/package.json +45 -24
  26. package/lib/types/compact-v2.d.ts +0 -104
  27. package/lib/types/dsh-compat.d.ts +0 -78
  28. package/lib/types/dsh-responses.d.ts +0 -82
  29. package/lib/types/grok-native-search.d.ts +0 -39
  30. package/lib/types/json-store.d.ts +0 -10
  31. package/lib/types/native-checkpoint.d.ts +0 -213
  32. package/lib/types/responses-request.d.ts +0 -59
  33. package/lib/types/responses-stream.d.ts +0 -64
  34. package/lib/types/route.d.ts +0 -153
  35. package/lib/types/service-mutex.d.ts +0 -14
  36. package/lib/types/token-budget.d.ts +0 -50
  37. package/lib/types/transport.d.ts +0 -21
  38. package/lib/types/web-run-output.d.ts +0 -29
  39. package/lib/types/web-search-alpha.d.ts +0 -286
  40. package/lib/types/web-search-capability.d.ts +0 -26
  41. package/lib/types/web-search-hosted.d.ts +0 -246
  42. package/lib/types/web-search-ref-store.d.ts +0 -22
@@ -0,0 +1,261 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ const activePolicy = new AsyncLocalStorage();
3
+ const projections = new WeakMap();
4
+ function scopedValue(values, target, key) {
5
+ const targetValues = values?.get(target);
6
+ return targetValues?.has(key)
7
+ ? { found: true, value: targetValues.get(key) }
8
+ : { found: false, value: undefined };
9
+ }
10
+ function setScopedValue(values, target, key, value) {
11
+ let targetValues = values.get(target);
12
+ if (!targetValues) {
13
+ targetValues = new Map();
14
+ values.set(target, targetValues);
15
+ }
16
+ targetValues.set(key, value);
17
+ }
18
+ function inheritedDescriptor(target, key) {
19
+ for (let current = Object.getPrototypeOf(target); current; current = Object.getPrototypeOf(current)) {
20
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
21
+ if (descriptor)
22
+ return descriptor;
23
+ }
24
+ return undefined;
25
+ }
26
+ function projectionShapeSupported(target, key, own) {
27
+ if (own)
28
+ return own.configurable === true && "value" in own && own.writable === true;
29
+ if (!Object.isExtensible(target))
30
+ return false;
31
+ const inherited = inheritedDescriptor(target, key);
32
+ if (!inherited)
33
+ return true;
34
+ return "value" in inherited
35
+ ? inherited.writable === true
36
+ : typeof inherited.set === "function";
37
+ }
38
+ function projectionStillInstalled(record) {
39
+ const current = Object.getOwnPropertyDescriptor(record.target, record.key);
40
+ return current?.get === record.getter && current.set === record.setter;
41
+ }
42
+ function installProjection(owner, target, key) {
43
+ let targetRecords = projections.get(target);
44
+ const existing = targetRecords?.get(key);
45
+ if (existing) {
46
+ if (!projectionStillInstalled(existing))
47
+ return undefined;
48
+ existing.owners.add(owner);
49
+ return existing;
50
+ }
51
+ const originalDescriptor = Object.getOwnPropertyDescriptor(target, key);
52
+ if (!projectionShapeSupported(target, key, originalDescriptor))
53
+ return undefined;
54
+ let originalValue;
55
+ try {
56
+ originalValue = Reflect.get(target, key, target);
57
+ }
58
+ catch {
59
+ return undefined;
60
+ }
61
+ const record = {};
62
+ record.target = target;
63
+ record.key = key;
64
+ record.originalDescriptor = originalDescriptor;
65
+ record.originalValue = originalValue;
66
+ record.baseValue = originalValue;
67
+ record.owners = new Set([owner]);
68
+ record.getter = () => {
69
+ const scoped = scopedValue(activePolicy.getStore(), target, key);
70
+ return scoped.found ? scoped.value : record.baseValue;
71
+ };
72
+ record.setter = (value) => {
73
+ const values = activePolicy.getStore();
74
+ if (values)
75
+ setScopedValue(values, target, key, value);
76
+ else
77
+ record.baseValue = value;
78
+ };
79
+ try {
80
+ Object.defineProperty(target, key, {
81
+ configurable: true,
82
+ enumerable: originalDescriptor?.enumerable ?? false,
83
+ get: record.getter,
84
+ set: record.setter,
85
+ });
86
+ }
87
+ catch {
88
+ return undefined;
89
+ }
90
+ if (!targetRecords) {
91
+ targetRecords = new Map();
92
+ projections.set(target, targetRecords);
93
+ }
94
+ targetRecords.set(key, record);
95
+ return record;
96
+ }
97
+ function restoreProjection(record) {
98
+ if (!projectionStillInstalled(record))
99
+ return;
100
+ try {
101
+ if (record.originalDescriptor) {
102
+ Object.defineProperty(record.target, record.key, {
103
+ ...record.originalDescriptor,
104
+ value: record.baseValue,
105
+ });
106
+ }
107
+ else if (record.baseValue === record.originalValue) {
108
+ delete record.target[record.key];
109
+ }
110
+ else {
111
+ Object.defineProperty(record.target, record.key, {
112
+ configurable: true,
113
+ enumerable: true,
114
+ writable: true,
115
+ value: record.baseValue,
116
+ });
117
+ }
118
+ }
119
+ catch { }
120
+ }
121
+ function operationError(signal) {
122
+ if (signal?.reason instanceof Error)
123
+ return signal.reason;
124
+ return new DOMException("The operation was aborted", "AbortError");
125
+ }
126
+ export class InvocationPolicyScope {
127
+ records = new Set();
128
+ queue = [];
129
+ idleWaiters = [];
130
+ sharedActive = 0;
131
+ exclusiveActive = false;
132
+ closed = false;
133
+ closeReason;
134
+ ensure(target, key) {
135
+ if (this.closed || !target)
136
+ return false;
137
+ const existing = projections.get(target)?.get(key);
138
+ if (existing && this.records.has(existing))
139
+ return projectionStillInstalled(existing);
140
+ const record = installProjection(this, target, key);
141
+ if (!record)
142
+ return false;
143
+ this.records.add(record);
144
+ return true;
145
+ }
146
+ acquire(mode, signal) {
147
+ if (this.closed)
148
+ return Promise.reject(this.closeReason ?? new Error("invocation policy scope closed"));
149
+ if (signal?.aborted)
150
+ return Promise.reject(operationError(signal));
151
+ if (this.queue.length === 0 &&
152
+ !this.exclusiveActive &&
153
+ (mode === "shared" || this.sharedActive === 0)) {
154
+ if (mode === "shared")
155
+ this.sharedActive += 1;
156
+ else
157
+ this.exclusiveActive = true;
158
+ return Promise.resolve(() => this.release(mode));
159
+ }
160
+ return new Promise((resolve, reject) => {
161
+ const waiter = { mode, resolve, reject, signal };
162
+ if (signal) {
163
+ const onAbort = () => {
164
+ const index = this.queue.indexOf(waiter);
165
+ if (index >= 0)
166
+ this.queue.splice(index, 1);
167
+ signal.removeEventListener("abort", onAbort);
168
+ reject(operationError(signal));
169
+ this.flushQueue();
170
+ };
171
+ waiter.onAbort = onAbort;
172
+ signal.addEventListener("abort", onAbort, { once: true });
173
+ }
174
+ this.queue.push(waiter);
175
+ });
176
+ }
177
+ release(mode) {
178
+ if (mode === "shared")
179
+ this.sharedActive -= 1;
180
+ else
181
+ this.exclusiveActive = false;
182
+ this.flushQueue();
183
+ this.resolveIdle();
184
+ }
185
+ flushQueue() {
186
+ if (this.exclusiveActive)
187
+ return;
188
+ while (this.queue.length > 0) {
189
+ const waiter = this.queue[0];
190
+ if (!waiter)
191
+ return;
192
+ if (waiter.signal?.aborted) {
193
+ this.queue.shift();
194
+ if (waiter.onAbort)
195
+ waiter.signal.removeEventListener("abort", waiter.onAbort);
196
+ waiter.reject(operationError(waiter.signal));
197
+ continue;
198
+ }
199
+ if (waiter.mode === "exclusive") {
200
+ if (this.sharedActive > 0)
201
+ return;
202
+ this.queue.shift();
203
+ if (waiter.signal && waiter.onAbort)
204
+ waiter.signal.removeEventListener("abort", waiter.onAbort);
205
+ this.exclusiveActive = true;
206
+ waiter.resolve(() => this.release("exclusive"));
207
+ return;
208
+ }
209
+ this.queue.shift();
210
+ if (waiter.signal && waiter.onAbort)
211
+ waiter.signal.removeEventListener("abort", waiter.onAbort);
212
+ this.sharedActive += 1;
213
+ waiter.resolve(() => this.release("shared"));
214
+ }
215
+ }
216
+ resolveIdle() {
217
+ if (this.sharedActive > 0 || this.exclusiveActive)
218
+ return;
219
+ const idle = this.idleWaiters.splice(0);
220
+ for (const resolve of idle)
221
+ resolve();
222
+ }
223
+ async run(signal, mode, task) {
224
+ const release = await this.acquire(mode, signal);
225
+ try {
226
+ // Every invocation is a new root. Nested agent calls must see host policy,
227
+ // not inherit another agent's projected config or pruner.
228
+ return await activePolicy.run(new Map(), task);
229
+ }
230
+ finally {
231
+ release();
232
+ }
233
+ }
234
+ close(reason = new Error("invocation policy scope closing")) {
235
+ if (!this.closed) {
236
+ this.closed = true;
237
+ this.closeReason = reason;
238
+ const queued = this.queue.splice(0);
239
+ for (const waiter of queued) {
240
+ if (waiter.signal && waiter.onAbort)
241
+ waiter.signal.removeEventListener("abort", waiter.onAbort);
242
+ waiter.reject(reason);
243
+ }
244
+ }
245
+ if (this.sharedActive === 0 && !this.exclusiveActive)
246
+ return Promise.resolve();
247
+ return new Promise((resolve) => this.idleWaiters.push(resolve));
248
+ }
249
+ restore() {
250
+ for (const record of this.records) {
251
+ record.owners.delete(this);
252
+ if (record.owners.size > 0)
253
+ continue;
254
+ restoreProjection(record);
255
+ const targetRecords = projections.get(record.target);
256
+ if (targetRecords?.get(record.key) === record)
257
+ targetRecords.delete(record.key);
258
+ }
259
+ this.records.clear();
260
+ }
261
+ }
package/lib/json-store.js CHANGED
@@ -10,21 +10,28 @@ export class JsonStore {
10
10
  empty;
11
11
  validate;
12
12
  corruptCode;
13
+ migrate;
13
14
  data;
14
- constructor(file, empty, validate, corruptCode = "LCX_STORE_CORRUPT") {
15
+ constructor(file, empty, validate, corruptCode = "LCX_STORE_CORRUPT", migrate) {
15
16
  this.file = file;
16
17
  this.empty = empty;
17
18
  this.validate = validate;
18
19
  this.corruptCode = corruptCode;
20
+ this.migrate = migrate;
19
21
  this.data = empty();
20
22
  this.refresh();
21
23
  }
22
24
  refresh() {
23
25
  try {
24
26
  const parsed = JSON.parse(readFileSync(this.file, "utf8"));
25
- if (!this.validate(parsed))
26
- throw new Error("invalid store");
27
- this.data = parsed;
27
+ if (this.validate(parsed))
28
+ this.data = parsed;
29
+ else {
30
+ const migrated = this.migrate?.(parsed);
31
+ if (migrated === undefined || !this.validate(migrated))
32
+ throw new Error("invalid store");
33
+ this.data = migrated;
34
+ }
28
35
  }
29
36
  catch (error) {
30
37
  if (errorCode(error) === "ENOENT") {