@inixiative/foundry-core 0.5.9 → 0.5.11
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/package.json +4 -4
- package/src/action-prompt.ts +11 -2
- package/src/adapters/file-memory.ts +5 -0
- package/src/adapters/http-memory.ts +5 -0
- package/src/adapters/markdown-docs.ts +12 -1
- package/src/adapters/markdown-hierarchy.ts +7 -2
- package/src/adapters/sqlite-memory.ts +21 -6
- package/src/base-agent.ts +5 -0
- package/src/bounded-set.ts +5 -0
- package/src/cache-lifecycle.ts +5 -0
- package/src/capability.ts +5 -0
- package/src/clarifier.ts +5 -0
- package/src/classifier.ts +5 -0
- package/src/context-layer.ts +10 -0
- package/src/context-stack.ts +5 -0
- package/src/credentials.ts +5 -0
- package/src/decider.ts +5 -0
- package/src/delivery-evidence.ts +5 -0
- package/src/event-stream.ts +5 -0
- package/src/executor.ts +17 -4
- package/src/feedback/archive-turns.ts +5 -0
- package/src/feedback/correction.ts +48 -2
- package/src/feedback/experiment-gate.ts +5 -0
- package/src/feedback/review-findings.ts +5 -0
- package/src/feedback/warden-labels.ts +5 -0
- package/src/feedback/warden-prefilter.ts +5 -0
- package/src/feedback/warden-probes.ts +5 -0
- package/src/harness.ts +7 -2
- package/src/hydrator.ts +5 -0
- package/src/id.ts +5 -0
- package/src/index.ts +25 -12
- package/src/intervention.ts +5 -0
- package/src/messages.ts +5 -0
- package/src/middleware.ts +5 -0
- package/src/model-registry.ts +92 -2
- package/src/native-evidence.ts +18 -0
- package/src/native-tools.ts +5 -0
- package/src/retry.ts +5 -0
- package/src/router.ts +5 -0
- package/src/scope.ts +5 -0
- package/src/serialized-queue.ts +35 -0
- package/src/session-delivery.ts +5 -0
- package/src/signal.ts +5 -0
- package/src/thread.ts +196 -21
- package/src/token-counts.ts +5 -0
- package/src/token-tracker.ts +49 -24
- package/src/tools.ts +6 -1
- package/src/trace.ts +5 -0
- package/src/types.ts +5 -2
- package/src/hooks.ts +0 -133
package/src/index.ts
CHANGED
|
@@ -140,6 +140,7 @@ export {
|
|
|
140
140
|
type SourceSegment,
|
|
141
141
|
type SourceSelectionReport,
|
|
142
142
|
segmentsText,
|
|
143
|
+
sha256Hex,
|
|
143
144
|
type VersionEntry,
|
|
144
145
|
type VersionLog,
|
|
145
146
|
} from './context-layer';
|
|
@@ -166,7 +167,13 @@ export {
|
|
|
166
167
|
} from './delivery-evidence';
|
|
167
168
|
// Observability
|
|
168
169
|
export { EventStream, type SessionEvent, type StreamEvent } from './event-stream';
|
|
169
|
-
export {
|
|
170
|
+
export {
|
|
171
|
+
type ExecuteHandler,
|
|
172
|
+
type ExecuteMeta,
|
|
173
|
+
Executor,
|
|
174
|
+
type ExecutorConfig,
|
|
175
|
+
withAfterMessageNotes,
|
|
176
|
+
} from './executor';
|
|
170
177
|
// Feedback: correction detection (the Prospector's), shared by Oracle, live capture and `foundry repeats`
|
|
171
178
|
export {
|
|
172
179
|
AGAIN_CORRECTION,
|
|
@@ -179,6 +186,7 @@ export {
|
|
|
179
186
|
type CorrectionDetection,
|
|
180
187
|
type CorrectionEvent,
|
|
181
188
|
type CorrectionSignal,
|
|
189
|
+
contextSecretHits,
|
|
182
190
|
correctionClassifyMessages,
|
|
183
191
|
correctionId,
|
|
184
192
|
detectCorrection,
|
|
@@ -187,6 +195,7 @@ export {
|
|
|
187
195
|
type FeedbackTag,
|
|
188
196
|
parseCorrectionClassifications,
|
|
189
197
|
proseOf,
|
|
198
|
+
SHAPED_SECRET_PATTERNS,
|
|
190
199
|
scrubSecrets,
|
|
191
200
|
type TranscriptTurn,
|
|
192
201
|
} from './feedback/correction';
|
|
@@ -292,16 +301,6 @@ export {
|
|
|
292
301
|
type PipelineStep,
|
|
293
302
|
type RequestContext,
|
|
294
303
|
} from './harness';
|
|
295
|
-
// Lifecycle Hooks (registry only — built-in hooks in @inixiative/foundry)
|
|
296
|
-
export {
|
|
297
|
-
type HookContext,
|
|
298
|
-
type HookHandler,
|
|
299
|
-
type HookPoint,
|
|
300
|
-
HookRegistry,
|
|
301
|
-
type HookResult,
|
|
302
|
-
type PlanModeConfig,
|
|
303
|
-
type PlanModeTrigger,
|
|
304
|
-
} from './hooks';
|
|
305
304
|
export {
|
|
306
305
|
type ContextRef,
|
|
307
306
|
type HydrationAdapter,
|
|
@@ -357,17 +356,20 @@ export {
|
|
|
357
356
|
type ModelVendor,
|
|
358
357
|
mainThreadLab,
|
|
359
358
|
modelCapabilities,
|
|
359
|
+
modelEfforts,
|
|
360
360
|
modelHasCapability,
|
|
361
361
|
modelOptionsByCapability,
|
|
362
362
|
type ProviderCredential,
|
|
363
363
|
type ProviderMode,
|
|
364
364
|
type ProviderType,
|
|
365
365
|
providersWithCapability,
|
|
366
|
+
REASONING_EFFORTS,
|
|
366
367
|
type ReasoningEffort,
|
|
367
368
|
type RuntimeKind,
|
|
368
369
|
registryModel,
|
|
369
370
|
resolveDecisionModel,
|
|
370
371
|
SUBSCRIPTION_DECISION_MODELS,
|
|
372
|
+
SUBSCRIPTION_WORKER_MODELS,
|
|
371
373
|
vendorModeProvider,
|
|
372
374
|
vendorOfProvider,
|
|
373
375
|
} from './model-registry';
|
|
@@ -390,6 +392,7 @@ export { type RetryConfig, retryMiddleware } from './retry';
|
|
|
390
392
|
export { type Route, type RouteHandler, Router, type RouterConfig } from './router';
|
|
391
393
|
// Ownership scope — which thread/project owns a source read or tool call
|
|
392
394
|
export { normalizeScope, type OwnershipScope } from './scope';
|
|
395
|
+
export { createSerializedQueue, type SerializedQueue } from './serialized-queue';
|
|
393
396
|
export {
|
|
394
397
|
type DeliveredPart,
|
|
395
398
|
layerPart,
|
|
@@ -408,12 +411,21 @@ export {
|
|
|
408
411
|
type DispatchOptions,
|
|
409
412
|
type FanResult,
|
|
410
413
|
Thread,
|
|
414
|
+
type ThreadAgentStatus,
|
|
415
|
+
type ThreadCheckout,
|
|
411
416
|
type ThreadConfig,
|
|
412
417
|
type ThreadContext,
|
|
418
|
+
type ThreadDone,
|
|
419
|
+
type ThreadFork,
|
|
420
|
+
type ThreadLoop,
|
|
421
|
+
type ThreadLoopRound,
|
|
422
|
+
type ThreadMachine,
|
|
413
423
|
type ThreadMeta,
|
|
414
424
|
type ThreadName,
|
|
425
|
+
type ThreadPlan,
|
|
426
|
+
type ThreadPlanItem,
|
|
415
427
|
type ThreadReference,
|
|
416
|
-
type
|
|
428
|
+
type ThreadSnooze,
|
|
417
429
|
type ThreadSpawn,
|
|
418
430
|
type ThreadStatus,
|
|
419
431
|
threadTitle,
|
|
@@ -428,6 +440,7 @@ export {
|
|
|
428
440
|
DEFAULT_COST_TABLE,
|
|
429
441
|
estimateTokens,
|
|
430
442
|
type ModelPricing,
|
|
443
|
+
modelPricing,
|
|
431
444
|
TokenTracker,
|
|
432
445
|
type TokenUsage,
|
|
433
446
|
type UsageAttribution,
|
package/src/intervention.ts
CHANGED
package/src/messages.ts
CHANGED
package/src/middleware.ts
CHANGED
package/src/model-registry.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @atlas
|
|
3
|
+
* @kind registry
|
|
4
|
+
* @partOf primitive:modelRegistry
|
|
5
|
+
*/
|
|
1
6
|
/**
|
|
2
7
|
* The model registry: the vocabulary of what models are worth using for, the
|
|
3
8
|
* table of providers and models, and the lookups over it.
|
|
@@ -18,6 +23,7 @@ export type ProviderType =
|
|
|
18
23
|
| 'gemini'
|
|
19
24
|
| 'claude-code'
|
|
20
25
|
| 'codex'
|
|
26
|
+
| 'muse'
|
|
21
27
|
| 'xai'
|
|
22
28
|
| 'typesafe'
|
|
23
29
|
| 'custom';
|
|
@@ -82,7 +88,17 @@ export const MODEL_CAPABILITIES: readonly ModelCapability[] = [
|
|
|
82
88
|
export type ProviderCredential = 'api-key' | 'subscription' | 'local';
|
|
83
89
|
|
|
84
90
|
/** Effort levels hosts publish. A superset of CompletionOpts.thinking. */
|
|
85
|
-
export
|
|
91
|
+
export const REASONING_EFFORTS = [
|
|
92
|
+
'none',
|
|
93
|
+
'low',
|
|
94
|
+
'medium',
|
|
95
|
+
'high',
|
|
96
|
+
'xhigh',
|
|
97
|
+
'max',
|
|
98
|
+
'ultra',
|
|
99
|
+
] as const;
|
|
100
|
+
/** The one effort vocabulary: every effort setting and picker is a subset of it. */
|
|
101
|
+
export type ReasoningEffort = (typeof REASONING_EFFORTS)[number];
|
|
86
102
|
|
|
87
103
|
/**
|
|
88
104
|
* How one model takes its reasoning controls. This is the map that replaced a
|
|
@@ -195,6 +211,13 @@ const MUSE_REASONING: ModelReasoning = {
|
|
|
195
211
|
fallback: 'medium',
|
|
196
212
|
outputField: 'max_completion_tokens',
|
|
197
213
|
};
|
|
214
|
+
/** Muse Code's catalogue (`<muse data>/model-catalog`): the CLI sends `effort` on each turn, high by default.
|
|
215
|
+
* `minimal` is offered too; Foundry's effort ladder starts at low. */
|
|
216
|
+
const MUSE_CODE_REASONING: ModelReasoning = {
|
|
217
|
+
param: 'reasoning_effort',
|
|
218
|
+
efforts: ['low', 'medium', 'high', 'xhigh', 'max'],
|
|
219
|
+
fallback: 'high',
|
|
220
|
+
};
|
|
198
221
|
|
|
199
222
|
export interface FoundryProviderInfo {
|
|
200
223
|
id: string;
|
|
@@ -236,6 +259,12 @@ export const SUBSCRIPTION_DECISION_MODELS = {
|
|
|
236
259
|
claude: DECISION_MODEL,
|
|
237
260
|
codex: 'gpt-5.6-luna',
|
|
238
261
|
} as const;
|
|
262
|
+
/** A subscription worker's main-thread model when a thread runs on a worker other than its project's default. */
|
|
263
|
+
export const SUBSCRIPTION_WORKER_MODELS = {
|
|
264
|
+
'claude-code': 'fable',
|
|
265
|
+
codex: 'gpt-6-astra',
|
|
266
|
+
muse: 'muse-wonder-1.0',
|
|
267
|
+
} as const;
|
|
239
268
|
|
|
240
269
|
/** Tag rule: every model judges. Cheap models review and route; capable models execute and advise. */
|
|
241
270
|
const FAST = ['judgment', 'learning-review', 'tool-use'] as ModelCapability[];
|
|
@@ -724,6 +753,55 @@ export const MODEL_REGISTRY: Record<string, FoundryProviderInfo> = {
|
|
|
724
753
|
},
|
|
725
754
|
],
|
|
726
755
|
},
|
|
756
|
+
muse: {
|
|
757
|
+
id: 'muse',
|
|
758
|
+
lab: 'meta',
|
|
759
|
+
type: 'muse',
|
|
760
|
+
label: 'Muse Code (Meta subscription)',
|
|
761
|
+
description:
|
|
762
|
+
"Native Muse Code harness (`muse serve`) using the user's own Muse login. Separate from Meta's pay-as-you-go Model API.",
|
|
763
|
+
credential: 'subscription',
|
|
764
|
+
// Off until the user turns on Meta's subscription mode: few machines have Muse Code signed in.
|
|
765
|
+
enabledByDefault: false,
|
|
766
|
+
models: [
|
|
767
|
+
// From the Muse Code 1.4.14 catalogue a Muse Code Everyday Usage login is served
|
|
768
|
+
// (`<muse data>/model-catalog`, 2026-11-01). The -contributor ids are hidden there and not listed.
|
|
769
|
+
{
|
|
770
|
+
id: 'muse-wonder-1.0',
|
|
771
|
+
label: 'Muse Wonder 1.0',
|
|
772
|
+
tier: 'powerful',
|
|
773
|
+
costTier: 'high',
|
|
774
|
+
contextWindow: 1_007_997,
|
|
775
|
+
maxOutputTokens: 128_000,
|
|
776
|
+
runtimeKind: 'native-harness',
|
|
777
|
+
capabilities: POWERFUL_REASONING,
|
|
778
|
+
reasoning: MUSE_CODE_REASONING,
|
|
779
|
+
notes: 'The Muse Code default.',
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
id: 'muse-spark-1.3',
|
|
783
|
+
label: 'Muse Spark 1.3',
|
|
784
|
+
tier: 'powerful',
|
|
785
|
+
costTier: 'high',
|
|
786
|
+
contextWindow: 1_007_997,
|
|
787
|
+
maxOutputTokens: 128_000,
|
|
788
|
+
runtimeKind: 'native-harness',
|
|
789
|
+
capabilities: POWERFUL_REASONING,
|
|
790
|
+
reasoning: MUSE_CODE_REASONING,
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
id: 'muse-spark-1.2',
|
|
794
|
+
label: 'Muse Spark 1.2',
|
|
795
|
+
tier: 'powerful',
|
|
796
|
+
costTier: 'high',
|
|
797
|
+
contextWindow: 1_007_997,
|
|
798
|
+
maxOutputTokens: 128_000,
|
|
799
|
+
runtimeKind: 'native-harness',
|
|
800
|
+
capabilities: POWERFUL_REASONING,
|
|
801
|
+
reasoning: { ...MUSE_CODE_REASONING, efforts: ['low', 'medium', 'high', 'xhigh'] },
|
|
802
|
+
},
|
|
803
|
+
],
|
|
804
|
+
},
|
|
727
805
|
meta: {
|
|
728
806
|
id: 'meta',
|
|
729
807
|
lab: 'meta',
|
|
@@ -1672,7 +1750,7 @@ export const MODEL_VENDORS: readonly ModelVendor[] = [
|
|
|
1672
1750
|
id: 'meta',
|
|
1673
1751
|
label: 'Meta (Muse)',
|
|
1674
1752
|
lab: 'meta',
|
|
1675
|
-
subscription: {
|
|
1753
|
+
subscription: { provider: 'muse' },
|
|
1676
1754
|
api: { provider: 'meta' },
|
|
1677
1755
|
},
|
|
1678
1756
|
{
|
|
@@ -1723,6 +1801,18 @@ export function modelOptionsByCapability(...capabilities: ModelCapability[]): Mo
|
|
|
1723
1801
|
);
|
|
1724
1802
|
}
|
|
1725
1803
|
|
|
1804
|
+
/**
|
|
1805
|
+
* The efforts a registered model accepts, in order; undefined for a model the registry does not
|
|
1806
|
+
* list (a local server's), which callers take as "not known, don't narrow".
|
|
1807
|
+
*/
|
|
1808
|
+
export function modelEfforts(
|
|
1809
|
+
providerId: string,
|
|
1810
|
+
modelId: string,
|
|
1811
|
+
): readonly ReasoningEffort[] | undefined {
|
|
1812
|
+
const model = registryModel(providerId, modelId);
|
|
1813
|
+
return model ? (model.reasoning?.efforts ?? []) : undefined;
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1726
1816
|
export function registryModel(providerId: string, modelId: string): FoundryModelInfo | undefined {
|
|
1727
1817
|
return MODEL_REGISTRY[providerId]?.models.find((model) => model.id === modelId);
|
|
1728
1818
|
}
|
package/src/native-evidence.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @atlas
|
|
3
|
+
* @kind transformer
|
|
4
|
+
* @partOf primitive:nativeSessions
|
|
5
|
+
*/
|
|
1
6
|
/** Public, owned projection. Raw protocol and reasoning are deliberately absent. */
|
|
2
7
|
export interface NativeOwner {
|
|
3
8
|
readonly threadId: string;
|
|
@@ -220,6 +225,8 @@ export interface NativeObservation {
|
|
|
220
225
|
observe(evidence: NativeEvidence): void | Promise<void>;
|
|
221
226
|
/** Receives the stop for this owner's registered admission, where the runtime acknowledges stops. */
|
|
222
227
|
interruptible?(interrupt: NativeInterrupt): void;
|
|
228
|
+
/** Receives how to steer more input into this owner's registered admission, or why it can't be. */
|
|
229
|
+
steerable?(steer: NativeSteer): void;
|
|
223
230
|
/**
|
|
224
231
|
* The executor's public thinking text, for live display only. It never becomes evidence:
|
|
225
232
|
* nothing here is journalled, traced or projected (reasoning stays out of NativeEvidence).
|
|
@@ -229,6 +236,17 @@ export interface NativeObservation {
|
|
|
229
236
|
/** `acknowledged`: the runtime confirmed the stop and the turn reached its native terminal. */
|
|
230
237
|
export type NativeInterruptOutcome = 'acknowledged' | 'no-turn' | 'unacknowledged';
|
|
231
238
|
export type NativeInterrupt = (opts?: { timeoutMs?: number }) => Promise<NativeInterruptOutcome>;
|
|
239
|
+
/** What became of a steer: taken into the running turn, sent but unconfirmed, or not delivered (with why). */
|
|
240
|
+
export type NativeSteerOutcome =
|
|
241
|
+
| { readonly outcome: 'steered' | 'unknown' }
|
|
242
|
+
| { readonly outcome: 'ignored'; readonly reason: string };
|
|
243
|
+
/**
|
|
244
|
+
* A running admission's steer (CORE-001): `push` adds text to that turn, where the runtime can steer.
|
|
245
|
+
* Where it can't, `push` is absent and `reason` says why, so the caller queues and says so.
|
|
246
|
+
*/
|
|
247
|
+
export type NativeSteer =
|
|
248
|
+
| { readonly push: (text: string) => Promise<NativeSteerOutcome> }
|
|
249
|
+
| { readonly push?: undefined; readonly reason: string };
|
|
232
250
|
export function freezeEvidence<T>(value: T): T {
|
|
233
251
|
const copy = structuredClone(value);
|
|
234
252
|
const freeze = (v: unknown) => {
|
package/src/native-tools.ts
CHANGED
package/src/retry.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @atlas
|
|
3
|
+
* @kind middleware
|
|
4
|
+
* @partOf primitive:middleware
|
|
5
|
+
*/
|
|
1
6
|
import { CapabilityDeniedError } from './capability';
|
|
2
7
|
import type { DispatchContext, Middleware, MiddlewareNext } from './middleware';
|
|
3
8
|
import { BudgetExceededError } from './token-tracker';
|
package/src/router.ts
CHANGED
package/src/scope.ts
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @atlas
|
|
3
|
+
* @kind utils
|
|
4
|
+
* @partOf primitive:concurrency
|
|
5
|
+
*/
|
|
6
|
+
// Copied from the template's packages/shared/src/utils/serializedQueue.ts.
|
|
7
|
+
// Each run(fn) waits for the previous to settle before invoking fn; a failure
|
|
8
|
+
// does not poison the chain. Errors still reject the caller's promise.
|
|
9
|
+
|
|
10
|
+
export type SerializedQueue = {
|
|
11
|
+
run: <T>(fn: () => Promise<T>) => Promise<T>;
|
|
12
|
+
size: () => number;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const createSerializedQueue = (): SerializedQueue => {
|
|
16
|
+
let tail: Promise<unknown> = Promise.resolve();
|
|
17
|
+
let pending = 0;
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
run: <T>(fn: () => Promise<T>): Promise<T> => {
|
|
21
|
+
pending++;
|
|
22
|
+
const wrapped = async (): Promise<T> => {
|
|
23
|
+
try {
|
|
24
|
+
return await fn();
|
|
25
|
+
} finally {
|
|
26
|
+
pending--;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const next = tail.then(wrapped, wrapped);
|
|
30
|
+
tail = next;
|
|
31
|
+
return next;
|
|
32
|
+
},
|
|
33
|
+
size: () => pending,
|
|
34
|
+
};
|
|
35
|
+
};
|
package/src/session-delivery.ts
CHANGED