@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.
Files changed (50) hide show
  1. package/package.json +4 -4
  2. package/src/action-prompt.ts +11 -2
  3. package/src/adapters/file-memory.ts +5 -0
  4. package/src/adapters/http-memory.ts +5 -0
  5. package/src/adapters/markdown-docs.ts +12 -1
  6. package/src/adapters/markdown-hierarchy.ts +7 -2
  7. package/src/adapters/sqlite-memory.ts +21 -6
  8. package/src/base-agent.ts +5 -0
  9. package/src/bounded-set.ts +5 -0
  10. package/src/cache-lifecycle.ts +5 -0
  11. package/src/capability.ts +5 -0
  12. package/src/clarifier.ts +5 -0
  13. package/src/classifier.ts +5 -0
  14. package/src/context-layer.ts +10 -0
  15. package/src/context-stack.ts +5 -0
  16. package/src/credentials.ts +5 -0
  17. package/src/decider.ts +5 -0
  18. package/src/delivery-evidence.ts +5 -0
  19. package/src/event-stream.ts +5 -0
  20. package/src/executor.ts +17 -4
  21. package/src/feedback/archive-turns.ts +5 -0
  22. package/src/feedback/correction.ts +48 -2
  23. package/src/feedback/experiment-gate.ts +5 -0
  24. package/src/feedback/review-findings.ts +5 -0
  25. package/src/feedback/warden-labels.ts +5 -0
  26. package/src/feedback/warden-prefilter.ts +5 -0
  27. package/src/feedback/warden-probes.ts +5 -0
  28. package/src/harness.ts +7 -2
  29. package/src/hydrator.ts +5 -0
  30. package/src/id.ts +5 -0
  31. package/src/index.ts +25 -12
  32. package/src/intervention.ts +5 -0
  33. package/src/messages.ts +5 -0
  34. package/src/middleware.ts +5 -0
  35. package/src/model-registry.ts +92 -2
  36. package/src/native-evidence.ts +18 -0
  37. package/src/native-tools.ts +5 -0
  38. package/src/retry.ts +5 -0
  39. package/src/router.ts +5 -0
  40. package/src/scope.ts +5 -0
  41. package/src/serialized-queue.ts +35 -0
  42. package/src/session-delivery.ts +5 -0
  43. package/src/signal.ts +5 -0
  44. package/src/thread.ts +196 -21
  45. package/src/token-counts.ts +5 -0
  46. package/src/token-tracker.ts +49 -24
  47. package/src/tools.ts +6 -1
  48. package/src/trace.ts +5 -0
  49. package/src/types.ts +5 -2
  50. 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 { type ExecuteHandler, type ExecuteMeta, Executor, type ExecutorConfig } from './executor';
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 ThreadSetup,
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,
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf primitive:signals
5
+ */
1
6
  import { newId } from './id';
2
7
  import type { Signal, SignalBus } from './signal';
3
8
  import type { Span, Trace } from './trace';
package/src/messages.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind helper
4
+ * @partOf primitive:nativeSessions
5
+ */
1
6
  import type {
2
7
  CompositionSnapshot,
3
8
  LayerInstanceState,
package/src/middleware.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf primitive:middleware
5
+ */
1
6
  import type { ExecutionResult } from './base-agent';
2
7
  import type { ContextStackView } from './context-stack';
3
8
 
@@ -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 type ReasoningEffort = 'none' | 'low' | 'medium' | 'high' | 'xhigh' | 'max' | 'ultra';
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: { comingSoon: true },
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
  }
@@ -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) => {
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind constant
4
+ * @partOf primitive:tools
5
+ */
1
6
  import type { Capability } from './capability';
2
7
 
3
8
  // Native harness tools by what they do: one list for Foundry's tool gate and work items, and for
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
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind agent
4
+ * @partOf primitive:agents
5
+ */
1
6
  import type { AgentConfig } from './base-agent';
2
7
  import type { ContextStack } from './context-stack';
3
8
  import { Decider, type DeciderConfig, type Decision } from './decider';
package/src/scope.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind type
4
+ * @partOf primitive:thread
5
+ */
1
6
  /**
2
7
  * Ownership scope — which thread and project an operation belongs to.
3
8
  *
@@ -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
+ };
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind helper
4
+ * @partOf primitive:nativeSessions
5
+ */
1
6
  import { computeHash } from './context-layer';
2
7
  import type { PromptBlock } from './context-stack';
3
8
 
package/src/signal.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf primitive:signals
5
+ */
1
6
  /**
2
7
  * Signal kinds — the Librarian's taxonomy.
3
8
  * Extensible via string union, not a closed enum.