@mastra/factory 0.1.0-alpha.9 → 0.2.0-alpha.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/CHANGELOG.md +125 -0
- package/dist/factory.js +139 -32
- package/dist/factory.js.map +1 -1
- package/dist/index.js +139 -32
- package/dist/index.js.map +1 -1
- package/dist/routes/config.d.ts +4 -0
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +89 -26
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +136 -31
- package/dist/routes/surface.js.map +1 -1
- package/dist/routes/work-items.d.ts.map +1 -1
- package/dist/routes/work-items.js +2 -1
- package/dist/routes/work-items.js.map +1 -1
- package/dist/rules/defaults.d.ts.map +1 -1
- package/dist/rules/defaults.js +3 -1
- package/dist/rules/defaults.js.map +1 -1
- package/dist/rules/github-service.d.ts.map +1 -1
- package/dist/rules/github-service.js +10 -2
- package/dist/rules/github-service.js.map +1 -1
- package/dist/rules/index.js +3 -1
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/start-coordinator.d.ts +3 -1
- package/dist/rules/start-coordinator.d.ts.map +1 -1
- package/dist/rules/start-coordinator.js +33 -1
- package/dist/rules/start-coordinator.js.map +1 -1
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,130 @@
|
|
|
1
1
|
# @mastra/factory
|
|
2
2
|
|
|
3
|
+
## 0.2.0-alpha.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added guided model-provider setup to Factory onboarding with a recommended default model and provider-specific observational-memory defaults. ([#20079](https://github.com/mastra-ai/mastra/pull/20079))
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Link Factory Review cards to their work item when a PR opens without recorded provenance. GitHub PR-opened ingress now falls back to matching the PR head branch against work item session branches, and Review intake records `headBranch`/`baseBranch` metadata so the board and session views can relate the cards. ([#20074](https://github.com/mastra-ai/mastra/pull/20074))
|
|
12
|
+
|
|
13
|
+
- Fixed board-started work sessions to use the Factory's default coding model and persisted observational-memory settings. ([#20081](https://github.com/mastra-ai/mastra/pull/20081))
|
|
14
|
+
|
|
15
|
+
- Restored observational-memory settings so Factory users can choose models and preferences before opening a chat session. ([#20079](https://github.com/mastra-ai/mastra/pull/20079))
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [[`55adddf`](https://github.com/mastra-ai/mastra/commit/55adddfda2a170b00c112bf37d677e8ce5b65d5a)]:
|
|
18
|
+
- @mastra/core@1.52.1-alpha.0
|
|
19
|
+
- @mastra/code-sdk@1.0.1-alpha.0
|
|
20
|
+
|
|
21
|
+
## 0.1.0
|
|
22
|
+
|
|
23
|
+
### Minor Changes
|
|
24
|
+
|
|
25
|
+
- Move the Factory project CRUD and source-control connection routes into `@mastra/factory` as a `ProjectRoutes` class. The routes take their storage handles (`FactoryProjectsStorage`, `SourceControlStorage`), the allowed version-control integration ids, and a `RouteAuth` adapter at construction time, replacing the old `ProjectDomain` that resolved domains through the `FactoryStorage` registry. The now-unused `FactoryDomain` base class was removed from the web host. ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
26
|
+
|
|
27
|
+
- Move the audit domain, agent git-action auditing, intake capabilities, and intake routes into `@mastra/factory`. `AuditDomain` now takes its storage handles (`AuditStorage`, `FactoryProjectsStorage`) and a `RouteAuth` adapter directly instead of resolving them through the factory storage registry, fans out to pluggable `AuditSink`s, and resolves agent tenants through an injected `agentTenant` callback. Intake routes ship as an `IntakeRoutes` class that calls `IntakeStorage` directly (the intermediate intake store module was removed). ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
28
|
+
|
|
29
|
+
- Added autonomous first-pass skills to the Software Factory. Work items now get an automatic investigation, planning, or review pass as soon as they enter the matching board column — no human input needed mid-run: ([#20058](https://github.com/mastra-ai/mastra/pull/20058))
|
|
30
|
+
|
|
31
|
+
- **factory-triage** runs when an issue enters triage: it investigates the issue, diagnoses the root cause, and requests a move to planning (or done if the issue should be closed).
|
|
32
|
+
- **factory-plan** runs when an item enters planning: it produces a phased implementation plan and requests a move to execute.
|
|
33
|
+
- **factory-review** runs when a pull request enters review: it reviews the changes, posts a verdict, and requests completion.
|
|
34
|
+
|
|
35
|
+
Instead of stopping to ask questions, the skills decide and record each decision as an assumption, batching assumptions and genuinely-human questions into one terminal handoff message. The superseded interactive skills (understand-issue, understand-pr) were removed.
|
|
36
|
+
|
|
37
|
+
- Move the `FactoryIntegration` contract and the OAuth `state` signer into `@mastra/factory`. The integration interface (routes, tools, diagnostics, intake/version-control capabilities, `IntegrationContext`) now lives at `@mastra/factory/integrations/base`, and `createStateSigner`/`StateSigner` at `@mastra/factory/state-signing`, so integrations can be implemented against the package without importing the web host. ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
38
|
+
|
|
39
|
+
- Added the @mastra/factory package. It now owns the Software Factory storage domains (projects, work items, intake, audit, credentials, integrations, model packs, queue health, source control) that previously lived inside the mastracode web app, so they can be reused outside the web server. ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
40
|
+
|
|
41
|
+
- Moved the server config routes and provider credential helpers into @mastra/factory as a reusable ConfigRoutes class. Route handlers now receive their auth checks through an injected RouteAuth seam and storage domains through constructor options, so hosts other than the Mastra Code web app can mount the same routes. ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
42
|
+
|
|
43
|
+
- Move the Factory work-item (kanban board) routes into `@mastra/factory` as a `WorkItemRoutes` class. The routes take their storage handles (`WorkItemsStorage`, `FactoryProjectsStorage`, `QueueHealthStorage`), an `AuditEmitter`, and a `RouteAuth` adapter at construction time. The request-body validators (`parseCreateWorkItem`, `parseUpdateWorkItem`) now live with the routes, the pass-through work-item store module was removed in favor of calling `WorkItemsStorage` directly, and `computeFactoryMetrics` takes a single object parameter. ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
44
|
+
|
|
45
|
+
### Patch Changes
|
|
46
|
+
|
|
47
|
+
- Move the WorkOS audit integration into `@mastra/factory/integrations/workos`. Its Admin Portal route now resolves the caller through the `RouteAuth` seam on `IntegrationContext` instead of web-host auth helpers, and `@mastra/auth-workos` becomes a package dependency. ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
48
|
+
|
|
49
|
+
- Move the factory auth module into `@mastra/factory/auth`. The provider-neutral ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
50
|
+
auth gating (`mountFactoryAuth`, `buildAuthRoutes`, `createFactoryAuthGate`),
|
|
51
|
+
the `RouteAuth` implementation (`createFactoryRouteAuth`), and the WorkOS/SSO
|
|
52
|
+
helpers now live next to the route seam they implement, with factory naming
|
|
53
|
+
throughout.
|
|
54
|
+
|
|
55
|
+
- The Factory's default `publicUrl` is now `http://localhost:4111` (the Factory server, which serves both the UI and the API) instead of `http://localhost:5173`. Generated Factory projects now run from a single server, so OAuth callback URLs and auth redirects derived from `publicUrl` point at the right origin out of the box. If you serve the SPA from a separate origin (for example a Vite dev server on :5173), set `publicUrl` (or `MASTRACODE_PUBLIC_URL`) explicitly. ([#20036](https://github.com/mastra-ai/mastra/pull/20036))
|
|
56
|
+
|
|
57
|
+
- Factory board now picks up new GitHub/Linear intake automatically (gentle 30s poll) and refreshes work-item positions immediately when the tab regains focus, instead of requiring a manual page reload ([#20071](https://github.com/mastra-ai/mastra/pull/20071))
|
|
58
|
+
|
|
59
|
+
- Fixed GitHub PATs saved in Settings not taking effect for the gh CLI in already-running Factory sessions until the server was restarted ([#20069](https://github.com/mastra-ai/mastra/pull/20069))
|
|
60
|
+
|
|
61
|
+
- Forwarded closed Platform GitHub event-log deliveries into Factory governance before dispatching repository subscriptions, and kept default GitHub rules from auto-starting issues or pull requests created before the Factory. ([#19988](https://github.com/mastra-ai/mastra/pull/19988))
|
|
62
|
+
|
|
63
|
+
- Track per-stage automation in Factory metrics. Stage history now stamps the exiting actor (`exitedBy`) alongside the entering one, `isAutomationActor` classifies rules-engine, agent (`agent:*`), and webhook (`github:*`) actors as automation, and `computeFactoryMetrics` reports a `stageAutomation` breakdown per stage: how many passes were fully automated (entered and exited by automation on the first visit) and how those automated passes ended up (`done`, `canceled`, `reworked`, or still in flight). Adds the `canceled` terminal stage to the board vocabulary (`FACTORY_RULE_STAGES`) — a tracked non-completion that feeds neither throughput nor cycle time — and rewords organization-required errors to be auth-provider neutral. ([#19844](https://github.com/mastra-ai/mastra/pull/19844))
|
|
64
|
+
|
|
65
|
+
- Fixed @mastra/factory build output so published modules use explicit .js import extensions and resolve correctly under Node ESM ([#19954](https://github.com/mastra-ai/mastra/pull/19954))
|
|
66
|
+
|
|
67
|
+
- Deployed factories now authenticate API and Studio requests with the same provider, so Studio sessions work without extra configuration. ([#19966](https://github.com/mastra-ai/mastra/pull/19966))
|
|
68
|
+
|
|
69
|
+
- Fixed Factory metrics windowing to use inclusive UTC calendar days. Date-only `from`/`to` bounds now include both selected days, an item completing at the current instant is counted in today's throughput (previously it could be dropped on the window's exclusive edge), and `windowDays` reflects the number of gap-filled day buckets. Cards feed the source mix only when created inside the window. ([#19971](https://github.com/mastra-ai/mastra/pull/19971))
|
|
70
|
+
|
|
71
|
+
- Fixed duplicate repositories in Factory source control settings. ([#19971](https://github.com/mastra-ai/mastra/pull/19971))
|
|
72
|
+
|
|
73
|
+
- Move the API-surface assembler from mastracode/web into @mastra/factory as `routes/surface` — `assembleWebApiRoutes` is now `assembleFactoryApiRoutes` and `WebApiRoutesDeps` is now `FactoryApiRoutesDeps`. The module composes fs/config/oauth/skills/intake/work-item routes plus every registered integration's route surface (with disabled-status stubs for absent github/linear integrations) from explicitly threaded dependency handles. ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
74
|
+
|
|
75
|
+
- Move the GitHub integration and the sandbox fleet into `@mastra/factory`. The fleet is now a DI-constructed `SandboxFleet` class (`@mastra/factory/sandbox/fleet`) that owns provisioning, reattach, teardown, idle windows, and per-replica budgets instead of reading a seeded runtime-config registry. The GitHub routes, webhook, sandbox materialization, project locks, and session subscriptions (`@mastra/factory/integrations/github`) resolve tenants through the `RouteAuth` seam and receive the fleet and factory storage via `IntegrationContext`, so the web host no longer exports `getSeededSandbox`/`getSeededGithubIntegration` service locators. ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
76
|
+
|
|
77
|
+
- Move the filesystem routes (`@mastra/factory/routes/fs`) and skill routes (`@mastra/factory/routes/skills`) into `@mastra/factory`. The skill prepare/invoke routes are now a `SkillRoutes` class that resolves users and tenants through the `RouteAuth` seam instead of web-host auth helpers. Diagnostics fields exposed by the GitHub and Linear integrations rename `webAuthEnabled` to `factoryAuthEnabled` to match the package's auth seam naming. ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
78
|
+
|
|
79
|
+
- Moved custom model providers and custom model packs off settings.json in the factory web app: both now live in the app database (org-scoped rows in deployed mode, a sentinel local scope in no-auth mode). Custom providers saved in the web settings page are picked up by model resolution and the model catalog through a new pluggable custom-providers source in the SDK, so the gateway no longer reads the host machine's settings.json for them, and models from your custom providers appear in the web model pickers. ([#19964](https://github.com/mastra-ai/mastra/pull/19964))
|
|
80
|
+
|
|
81
|
+
Hosts that store custom providers elsewhere (like the factory's database) register a source at boot; when none is registered, the SDK keeps reading settings.json as before:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import { setCustomProvidersSource } from '@mastra/code-sdk/agents/custom-provider-source';
|
|
85
|
+
|
|
86
|
+
setCustomProvidersSource(tenant => (tenant ? snapshotForOrg(tenant.orgId) : []));
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- Fixed cloned session threads reading from a previous storage instance. The dynamic memory cache now invalidates when the storage or vector instance changes, so thread cloning always uses the current database. ([#19966](https://github.com/mastra-ai/mastra/pull/19966))
|
|
90
|
+
|
|
91
|
+
- Added a memory-settings storage domain: observational memory settings (observer and reflector models, thresholds, attachment observation) changed in the web app are now stored in the app database — one row per user — instead of settings.json, and the settings page reads them back from the database. Factory-mounted agent controllers no longer seed observational memory settings from the host machine's settings.json (new `disableSettingsOmSeed` SDK option), so server sessions start from built-in defaults plus whatever is stored in the database. The OM settings model pickers in the web UI are now searchable comboboxes. ([#19964](https://github.com/mastra-ai/mastra/pull/19964))
|
|
92
|
+
|
|
93
|
+
Server embedders that persist memory settings in their own database can opt out of the settings.json seed:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { createMastraCode } from '@mastra/code-sdk';
|
|
97
|
+
|
|
98
|
+
const mastraCode = await createMastraCode({
|
|
99
|
+
cwd: process.cwd(),
|
|
100
|
+
// Don't seed observer/reflector models or thresholds from the host
|
|
101
|
+
// machine's settings.json — sessions start from built-in defaults.
|
|
102
|
+
disableSettingsOmSeed: true,
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
- Move the Linear integration into `@mastra/factory/integrations/linear`. `LinearIntegration` now owns the full connection lifecycle (OAuth token exchange, single-flight refresh, scope checks, and connection caching) as class methods, the routes and agent tools resolve tenants through the `RouteAuth` seam instead of web-host auth imports, and the `getSeededIntegration` runtime-config indirection is gone — the host hands the integration instance and storage handles directly via `initialize()`. ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
107
|
+
|
|
108
|
+
- Fixed Factory automation so polled GitHub events reach governance rules, authenticated sessions start with the correct ownership, and board moves reliably notify active or idle agents. ([#19979](https://github.com/mastra-ai/mastra/pull/19979))
|
|
109
|
+
|
|
110
|
+
- Move the `MastraFactory` assembly root into `@mastra/factory`. `factory-entry.ts` now lives at the package root export (`@mastra/factory`), alongside the extracted `workspace`, `spa-static`, `server-error`, and `sandbox/reattach` helpers. Factory skills ship with the package and are copied into deploy output via the consuming app's build script. ([#19866](https://github.com/mastra-ai/mastra/pull/19866))
|
|
111
|
+
|
|
112
|
+
- Fixed web chat sessions getting stuck in a "Connection lost — reconnecting…" loop while the session workspace was still starting up ([#20067](https://github.com/mastra-ai/mastra/pull/20067))
|
|
113
|
+
|
|
114
|
+
- Fixed a server startup crash when the factory's storage backend could not be recognized by the SDK. The factory now tells the SDK explicitly whether its Mastra store is Postgres or LibSQL, so agent state wiring works even when the project's dependency graph contains duplicate copies of Mastra packages. ([#20030](https://github.com/mastra-ai/mastra/pull/20030))
|
|
115
|
+
|
|
116
|
+
- Updated dependencies [[`a4d7c7d`](https://github.com/mastra-ai/mastra/commit/a4d7c7d74f423efc73b3e4db8142478763e6989d), [`ec857fc`](https://github.com/mastra-ai/mastra/commit/ec857fc79c264b53b38e16478c789b7177f2ad59), [`41a5392`](https://github.com/mastra-ai/mastra/commit/41a5392d9f6c5e18d6b227f0fc0ddf49c50774e9), [`ec857fc`](https://github.com/mastra-ai/mastra/commit/ec857fc79c264b53b38e16478c789b7177f2ad59), [`d7385ad`](https://github.com/mastra-ai/mastra/commit/d7385ad9e88f9e4f33d15c0ec0bfebedde0cbc2e), [`41a5392`](https://github.com/mastra-ai/mastra/commit/41a5392d9f6c5e18d6b227f0fc0ddf49c50774e9), [`3d6e539`](https://github.com/mastra-ai/mastra/commit/3d6e539272eb2ea0407034605ee1906b3be06b39), [`1426af2`](https://github.com/mastra-ai/mastra/commit/1426af24975879c000d13ac75673f630fcc970c1), [`a40adeb`](https://github.com/mastra-ai/mastra/commit/a40adeb222b961a56a58af56a106106525721b74), [`8a0d145`](https://github.com/mastra-ai/mastra/commit/8a0d145aadbdf7278665aceaaec364b35dd9bd94), [`bd2f1d2`](https://github.com/mastra-ai/mastra/commit/bd2f1d274d05e60e2366f005ea0d94d5cea0d5ff), [`b4b7ea8`](https://github.com/mastra-ai/mastra/commit/b4b7ea8733f033fc441ea47ed03f6afb17ec2248), [`d2a51c1`](https://github.com/mastra-ai/mastra/commit/d2a51c13c92c22f82bba8b4f48e746a2cc1aecdf), [`e1f2fae`](https://github.com/mastra-ai/mastra/commit/e1f2faebaf048c3d4c2e2c01d293767c195d5794), [`63aa799`](https://github.com/mastra-ai/mastra/commit/63aa799c6b44eacc7806cda6846b7c5bbee06b37), [`b7e79c3`](https://github.com/mastra-ai/mastra/commit/b7e79c3c02ac5cd415db34ba0975ceafc1464333), [`675fbff`](https://github.com/mastra-ai/mastra/commit/675fbff84d3274391b33e852f76083c38a5514e5), [`55b6ecd`](https://github.com/mastra-ai/mastra/commit/55b6ecd1083d21d00ea19488e721e451de75e76f), [`dfc7769`](https://github.com/mastra-ai/mastra/commit/dfc77695549e4434873051ddd1f6065330ed5ab8), [`da009e1`](https://github.com/mastra-ai/mastra/commit/da009e1aacd89ed94b8d1b2af09c9d4fe7c4db49), [`3b77e77`](https://github.com/mastra-ai/mastra/commit/3b77e7704936522e4769d29de1b5ea6901f302bd), [`c7d30cd`](https://github.com/mastra-ai/mastra/commit/c7d30cd86009c407df91105591f03cd6e3d2854d), [`21a0eb8`](https://github.com/mastra-ai/mastra/commit/21a0eb86746ba0b703acea360d4f84c6a5a493f2), [`8b20926`](https://github.com/mastra-ai/mastra/commit/8b20926cd59e2ba3d66458e062fa0e6e2ada3e68), [`b4b7ea8`](https://github.com/mastra-ai/mastra/commit/b4b7ea8733f033fc441ea47ed03f6afb17ec2248), [`975295d`](https://github.com/mastra-ai/mastra/commit/975295d418552f0d46a59edfef4c3ee555f9930a), [`73db8db`](https://github.com/mastra-ai/mastra/commit/73db8db90d69ab6153c7942749f624db0d96952d), [`6b1bf3b`](https://github.com/mastra-ai/mastra/commit/6b1bf3b9494bd51aa8f654c68c9355d6046fa2a1), [`35c2181`](https://github.com/mastra-ai/mastra/commit/35c2181e6a50e47c90ba36260db7c9723d54696f), [`0a2c22c`](https://github.com/mastra-ai/mastra/commit/0a2c22c902604439ec490319e14c17f331e0c84c), [`cc656b9`](https://github.com/mastra-ai/mastra/commit/cc656b92cc8fe40af3e2ea8bb796a6b406e96791), [`4cfdd64`](https://github.com/mastra-ai/mastra/commit/4cfdd645794feaea0c4ea711e70ecdfbef0c5b8e), [`232fcbc`](https://github.com/mastra-ai/mastra/commit/232fcbc14fce625dd672ba043329c0b732c62be2), [`b75d749`](https://github.com/mastra-ai/mastra/commit/b75d749621ff5d17e86bcb4ee809d301fb4f7cf3), [`821648b`](https://github.com/mastra-ai/mastra/commit/821648bf2871ef840100c7bacbecf676010bd12a), [`de86fd7`](https://github.com/mastra-ai/mastra/commit/de86fd7119f0438381d1a642e3d258143c0b9c29), [`d2a51c1`](https://github.com/mastra-ai/mastra/commit/d2a51c13c92c22f82bba8b4f48e746a2cc1aecdf), [`2745031`](https://github.com/mastra-ai/mastra/commit/2745031d1d4a4978f037092da371428c32e2842a), [`b4b7ea8`](https://github.com/mastra-ai/mastra/commit/b4b7ea8733f033fc441ea47ed03f6afb17ec2248), [`cc656b9`](https://github.com/mastra-ai/mastra/commit/cc656b92cc8fe40af3e2ea8bb796a6b406e96791), [`ef03fbc`](https://github.com/mastra-ai/mastra/commit/ef03fbcc556bcbc04c9b3d06fab88771ecaa043c), [`3a8024c`](https://github.com/mastra-ai/mastra/commit/3a8024ce615f8aa89479c0d71fe61d10bb0040be), [`bb92559`](https://github.com/mastra-ai/mastra/commit/bb9255954be8323a5ecab7595fe5365c564b3f52), [`35865a5`](https://github.com/mastra-ai/mastra/commit/35865a53e194aa9634d6a70a97010e7a6b9d58b1), [`67dd8b5`](https://github.com/mastra-ai/mastra/commit/67dd8b594d8b87a3a4d4ca7659f57d89fe8312a6), [`f9717e4`](https://github.com/mastra-ai/mastra/commit/f9717e4a381500042d088577347a787b0ec8caff), [`74faf8b`](https://github.com/mastra-ai/mastra/commit/74faf8bd9c1018f2492653c06b1e25fc8300e9e6), [`ef03fbc`](https://github.com/mastra-ai/mastra/commit/ef03fbcc556bcbc04c9b3d06fab88771ecaa043c), [`675fbff`](https://github.com/mastra-ai/mastra/commit/675fbff84d3274391b33e852f76083c38a5514e5), [`70687f7`](https://github.com/mastra-ai/mastra/commit/70687f7e495a322a02070b4a67cb0c77a5ca91ec), [`1fadac4`](https://github.com/mastra-ai/mastra/commit/1fadac44537caeefe81f9f775ae2f2f3d94e9069), [`73db8db`](https://github.com/mastra-ai/mastra/commit/73db8db90d69ab6153c7942749f624db0d96952d), [`76b7181`](https://github.com/mastra-ai/mastra/commit/76b71810366e6d90b9d3973149d1c7ba3659ffb9), [`6341b72`](https://github.com/mastra-ai/mastra/commit/6341b720fa80e65731cbbd7d88d1088f4c5b9914), [`792ec9a`](https://github.com/mastra-ai/mastra/commit/792ec9a0869bab8274cf5e0ed2840738737a1607), [`85e4fb5`](https://github.com/mastra-ai/mastra/commit/85e4fb50087a81c74df3a762f53b56373db0b912), [`712b864`](https://github.com/mastra-ai/mastra/commit/712b864aa1ed12b14c54390ec17b69de163c37f7), [`85e4fb5`](https://github.com/mastra-ai/mastra/commit/85e4fb50087a81c74df3a762f53b56373db0b912), [`9bffb73`](https://github.com/mastra-ai/mastra/commit/9bffb73e9ea46f48b53205b35a69a57f70912c78), [`0c0e8d7`](https://github.com/mastra-ai/mastra/commit/0c0e8d7becd4d1445c656b78d5d845f606c1ff9d), [`a7bbe77`](https://github.com/mastra-ai/mastra/commit/a7bbe773577f60bc4761b534ef7ec6b476332dad), [`eec6a54`](https://github.com/mastra-ai/mastra/commit/eec6a54c64cd365c9b75c14a02e32122ad5f657c), [`72e437c`](https://github.com/mastra-ai/mastra/commit/72e437c515942c80b9def5b026e0bdee61b469d9), [`8f7a5de`](https://github.com/mastra-ai/mastra/commit/8f7a5dedc246cdc938bb65516703cf9b27b03756), [`a7bbe77`](https://github.com/mastra-ai/mastra/commit/a7bbe773577f60bc4761b534ef7ec6b476332dad), [`11f6cd9`](https://github.com/mastra-ai/mastra/commit/11f6cd96fe42582403416608beb212cc1a2cc79e), [`337d41d`](https://github.com/mastra-ai/mastra/commit/337d41d8aae0399d2bf42d42ebddac0c21953891), [`ef03c0c`](https://github.com/mastra-ai/mastra/commit/ef03c0cfc62367a458e4cc56462e2148b35681c5), [`4fb4d88`](https://github.com/mastra-ai/mastra/commit/4fb4d881bc107acee13890ad4d78661016c510ed), [`da009e1`](https://github.com/mastra-ai/mastra/commit/da009e1aacd89ed94b8d1b2af09c9d4fe7c4db49), [`4e68363`](https://github.com/mastra-ai/mastra/commit/4e683634f94ebd062d26a3bb6093a8dfc7263d37), [`c328769`](https://github.com/mastra-ai/mastra/commit/c3287698ff8ef98dba86d415faa566fa3e5f4d56), [`eec6a54`](https://github.com/mastra-ai/mastra/commit/eec6a54c64cd365c9b75c14a02e32122ad5f657c), [`d7f5f9e`](https://github.com/mastra-ai/mastra/commit/d7f5f9e5d76ed588842bce30fac076ec9e3ad98a), [`9f7c67a`](https://github.com/mastra-ai/mastra/commit/9f7c67abeeb52c41c51a9b5edee60b62afe7cd8d), [`c46bb46`](https://github.com/mastra-ai/mastra/commit/c46bb461636ce3a8d45ecd7fc5d4a58803360cd0), [`3b65e68`](https://github.com/mastra-ai/mastra/commit/3b65e68d7f1c771c7a70eea42d83fefdd28cad88), [`4eba27a`](https://github.com/mastra-ai/mastra/commit/4eba27adcf60f991df0e62f94b3e75b4e67f3b4b), [`c701be3`](https://github.com/mastra-ai/mastra/commit/c701be32d7d9aa94a66da8c6cc38dcac6856f464), [`db650ce`](https://github.com/mastra-ai/mastra/commit/db650ce490348914e85b93651d83acdf8f2a4c31), [`232fcbc`](https://github.com/mastra-ai/mastra/commit/232fcbc14fce625dd672ba043329c0b732c62be2), [`6354eeb`](https://github.com/mastra-ai/mastra/commit/6354eeb32efa9f5f68f51dda394e90e2ee76f1fb), [`a8799bb`](https://github.com/mastra-ai/mastra/commit/a8799bb8e44f4a60d01e4e2acd3448ff80bf14f8), [`3d6e539`](https://github.com/mastra-ai/mastra/commit/3d6e539272eb2ea0407034605ee1906b3be06b39), [`e3868e2`](https://github.com/mastra-ai/mastra/commit/e3868e22babfffd0133771669ca724501c2dd58e), [`b06a569`](https://github.com/mastra-ai/mastra/commit/b06a56958d683e45574d2e3806dca42db5fe8a7a), [`9251370`](https://github.com/mastra-ai/mastra/commit/9251370ad413af464aa22d7566338bec5613e8de), [`b87e4ca`](https://github.com/mastra-ai/mastra/commit/b87e4cad9acf70e58c1559da0ca3640d5ae25e6e), [`3491666`](https://github.com/mastra-ai/mastra/commit/34916663c4fdd43b48c21f4ab2d5fb6dcccc94f9), [`c0bec73`](https://github.com/mastra-ai/mastra/commit/c0bec732c93d1a22ae5e51ed66cf8cacca8bd6a6)]:
|
|
117
|
+
- @mastra/auth-workos@1.6.4
|
|
118
|
+
- @mastra/code-sdk@1.0.0
|
|
119
|
+
- @mastra/core@1.52.0
|
|
120
|
+
- @mastra/auth-studio@1.3.2
|
|
121
|
+
|
|
122
|
+
## 0.1.0-alpha.10
|
|
123
|
+
|
|
124
|
+
### Patch Changes
|
|
125
|
+
|
|
126
|
+
- Factory board now picks up new GitHub/Linear intake automatically (gentle 30s poll) and refreshes work-item positions immediately when the tab regains focus, instead of requiring a manual page reload ([#20071](https://github.com/mastra-ai/mastra/pull/20071))
|
|
127
|
+
|
|
3
128
|
## 0.1.0-alpha.9
|
|
4
129
|
|
|
5
130
|
### Patch Changes
|
package/dist/factory.js
CHANGED
|
@@ -30392,6 +30392,7 @@ var FactoryGithubEventService = class {
|
|
|
30392
30392
|
repositoryId,
|
|
30393
30393
|
issueNumber,
|
|
30394
30394
|
pullRequestNumber,
|
|
30395
|
+
string(object(pullRequest?.head)?.ref),
|
|
30395
30396
|
provenance
|
|
30396
30397
|
);
|
|
30397
30398
|
const actor = await githubActor(this.options.github, {
|
|
@@ -30486,7 +30487,7 @@ var FactoryGithubEventService = class {
|
|
|
30486
30487
|
});
|
|
30487
30488
|
return { status: committed.status };
|
|
30488
30489
|
}
|
|
30489
|
-
async #relatedItem(orgId, projectId, repositoryId, issueNumber, pullRequestNumber, provenance) {
|
|
30490
|
+
async #relatedItem(orgId, projectId, repositoryId, issueNumber, pullRequestNumber, pullRequestHeadBranch, provenance) {
|
|
30490
30491
|
const items = await this.options.storage.list({ orgId, factoryProjectId: projectId });
|
|
30491
30492
|
if (provenance) return items.find((item) => item.id === provenance.workItemId);
|
|
30492
30493
|
if (issueNumber) {
|
|
@@ -30495,7 +30496,14 @@ var FactoryGithubEventService = class {
|
|
|
30495
30496
|
if (pullRequestNumber) {
|
|
30496
30497
|
return items.find((item) => item.externalSource?.externalId === canonicalSourceKey("pull-request", pullRequestNumber)) ?? items.find(
|
|
30497
30498
|
(item) => item.externalSource?.externalId === legacySourceKey(repositoryId, "pull-request", pullRequestNumber)
|
|
30498
|
-
)
|
|
30499
|
+
) ?? // Provenance fallback: a PR pushed from a work item's session branch
|
|
30500
|
+
// belongs to that item even when no gh-pr-create provenance was
|
|
30501
|
+
// recorded (session predating state seeding, or the PR was opened
|
|
30502
|
+
// outside the tracked tool call). Session branches are per-item
|
|
30503
|
+
// (`factory/issue-N`), so a head-branch match is unambiguous.
|
|
30504
|
+
(pullRequestHeadBranch ? items.find(
|
|
30505
|
+
(item) => item.externalSource?.type !== "pull-request" && Object.values(item.sessions).some((session) => session.branch === pullRequestHeadBranch)
|
|
30506
|
+
) : void 0);
|
|
30499
30507
|
}
|
|
30500
30508
|
return void 0;
|
|
30501
30509
|
}
|
|
@@ -30650,16 +30658,28 @@ async function configureThread(session, request) {
|
|
|
30650
30658
|
await Promise.all(Object.entries(settings).map(([key, value]) => session.thread.setSetting({ key, value })));
|
|
30651
30659
|
return threadId;
|
|
30652
30660
|
}
|
|
30661
|
+
async function applyMemorySettings(session, record) {
|
|
30662
|
+
if (record?.observerModelId) await session.om.observer.switchModel({ modelId: record.observerModelId });
|
|
30663
|
+
if (record?.reflectorModelId) await session.om.reflector.switchModel({ modelId: record.reflectorModelId });
|
|
30664
|
+
const state = {
|
|
30665
|
+
...record?.observationThreshold != null ? { observationThreshold: record.observationThreshold } : {},
|
|
30666
|
+
...record?.reflectionThreshold != null ? { reflectionThreshold: record.reflectionThreshold } : {},
|
|
30667
|
+
...record?.observeAttachments != null ? { observeAttachments: record.observeAttachments } : {}
|
|
30668
|
+
};
|
|
30669
|
+
if (Object.keys(state).length > 0) await session.state.set(state);
|
|
30670
|
+
}
|
|
30653
30671
|
var FactoryStartCoordinator = class {
|
|
30654
30672
|
#controller;
|
|
30655
30673
|
#storage;
|
|
30656
30674
|
#transitionService;
|
|
30657
30675
|
#sourceControl;
|
|
30658
|
-
|
|
30676
|
+
#memorySettings;
|
|
30677
|
+
constructor(controller, storage, transitionService, sourceControl, memorySettings) {
|
|
30659
30678
|
this.#controller = controller;
|
|
30660
30679
|
this.#storage = storage;
|
|
30661
30680
|
this.#transitionService = transitionService;
|
|
30662
30681
|
this.#sourceControl = sourceControl;
|
|
30682
|
+
this.#memorySettings = memorySettings;
|
|
30663
30683
|
}
|
|
30664
30684
|
async prepare(request) {
|
|
30665
30685
|
const storage = this.#storage;
|
|
@@ -30682,6 +30702,26 @@ var FactoryStartCoordinator = class {
|
|
|
30682
30702
|
tags: sessionState
|
|
30683
30703
|
});
|
|
30684
30704
|
await session.state.set(sessionState);
|
|
30705
|
+
if (this.#memorySettings) {
|
|
30706
|
+
try {
|
|
30707
|
+
const record = await this.#memorySettings.get({ orgId: request.orgId, userId: request.userId });
|
|
30708
|
+
await applyMemorySettings(session, record);
|
|
30709
|
+
} catch (error) {
|
|
30710
|
+
console.warn("[Factory Start] Failed to apply observational-memory settings", {
|
|
30711
|
+
error: error instanceof Error ? error.message : String(error)
|
|
30712
|
+
});
|
|
30713
|
+
}
|
|
30714
|
+
}
|
|
30715
|
+
if (request.defaultModelId) {
|
|
30716
|
+
try {
|
|
30717
|
+
await session.model.switch({ modelId: request.defaultModelId });
|
|
30718
|
+
} catch (error) {
|
|
30719
|
+
console.warn("[Factory Start] Failed to apply factory default model", {
|
|
30720
|
+
modelId: request.defaultModelId,
|
|
30721
|
+
error: error instanceof Error ? error.message : String(error)
|
|
30722
|
+
});
|
|
30723
|
+
}
|
|
30724
|
+
}
|
|
30685
30725
|
const threadId = await configureThread(session, request);
|
|
30686
30726
|
const kickoffMessage = await resolveKickoffMessage(session, request.invocation);
|
|
30687
30727
|
const prepared = await storage.prepareRunStart({
|
|
@@ -31167,6 +31207,16 @@ async function applyPackToSession({
|
|
|
31167
31207
|
}
|
|
31168
31208
|
var DEFAULT_OBSERVATION_THRESHOLD = 3e4;
|
|
31169
31209
|
var DEFAULT_REFLECTION_THRESHOLD = 4e4;
|
|
31210
|
+
function providerOMModelId(providerId, factoryModelId) {
|
|
31211
|
+
switch (providerId) {
|
|
31212
|
+
case "anthropic":
|
|
31213
|
+
return "anthropic/claude-haiku-4-5";
|
|
31214
|
+
case "openai":
|
|
31215
|
+
return "openai/gpt-5.4-mini";
|
|
31216
|
+
default:
|
|
31217
|
+
return factoryModelId || DEFAULT_OM_MODEL_ID;
|
|
31218
|
+
}
|
|
31219
|
+
}
|
|
31170
31220
|
function readOMConfig(session) {
|
|
31171
31221
|
const state = session.state.get() ?? {};
|
|
31172
31222
|
const observeAttachments = state.observeAttachments;
|
|
@@ -31178,6 +31228,15 @@ function readOMConfig(session) {
|
|
|
31178
31228
|
observeAttachments: observeAttachments === true || observeAttachments === false ? observeAttachments : "auto"
|
|
31179
31229
|
};
|
|
31180
31230
|
}
|
|
31231
|
+
function readStoredOMConfig(record) {
|
|
31232
|
+
return {
|
|
31233
|
+
observerModelId: record?.observerModelId ?? DEFAULT_OM_MODEL_ID,
|
|
31234
|
+
reflectorModelId: record?.reflectorModelId ?? DEFAULT_OM_MODEL_ID,
|
|
31235
|
+
observationThreshold: record?.observationThreshold ?? DEFAULT_OBSERVATION_THRESHOLD,
|
|
31236
|
+
reflectionThreshold: record?.reflectionThreshold ?? DEFAULT_REFLECTION_THRESHOLD,
|
|
31237
|
+
observeAttachments: record?.observeAttachments ?? "auto"
|
|
31238
|
+
};
|
|
31239
|
+
}
|
|
31181
31240
|
async function resolveMemorySettingsContext({
|
|
31182
31241
|
c,
|
|
31183
31242
|
auth,
|
|
@@ -31587,19 +31646,60 @@ var ConfigRoutes = class extends Route {
|
|
|
31587
31646
|
}
|
|
31588
31647
|
}
|
|
31589
31648
|
}),
|
|
31649
|
+
registerApiRoute7("/web/config/om/provider-defaults", {
|
|
31650
|
+
method: "POST",
|
|
31651
|
+
requiresAuth: false,
|
|
31652
|
+
handler: async (c) => {
|
|
31653
|
+
let body;
|
|
31654
|
+
try {
|
|
31655
|
+
body = await c.req.json();
|
|
31656
|
+
} catch {
|
|
31657
|
+
return c.json({ error: "Invalid JSON body" }, 400);
|
|
31658
|
+
}
|
|
31659
|
+
const providerId = typeof body.providerId === "string" ? body.providerId.trim() : "";
|
|
31660
|
+
const factoryModelId = typeof body.factoryModelId === "string" ? body.factoryModelId.trim() : "";
|
|
31661
|
+
if (!providerId) return c.json({ error: "Missing required field: providerId" }, 400);
|
|
31662
|
+
const context = await resolveMemorySettingsContext({
|
|
31663
|
+
c: loose6(c),
|
|
31664
|
+
auth,
|
|
31665
|
+
memorySettings: options.memorySettings
|
|
31666
|
+
});
|
|
31667
|
+
if ("response" in context) return context.response;
|
|
31668
|
+
try {
|
|
31669
|
+
const tenantCredentials = await listTenantCredentialsForRequest({
|
|
31670
|
+
c: loose6(c),
|
|
31671
|
+
auth,
|
|
31672
|
+
credentials: options.modelCredentials
|
|
31673
|
+
});
|
|
31674
|
+
const access = await buildProviderAccess({
|
|
31675
|
+
controller,
|
|
31676
|
+
authStorage: tenantCredentials ? void 0 : authStorage,
|
|
31677
|
+
tenantCredentials
|
|
31678
|
+
});
|
|
31679
|
+
if (!access[providerId]) return c.json({ error: `Provider "${providerId}" is not configured` }, 400);
|
|
31680
|
+
const modelId = providerOMModelId(providerId, factoryModelId);
|
|
31681
|
+
const record = await context.storage.patch({
|
|
31682
|
+
orgId: context.orgId,
|
|
31683
|
+
userId: context.userId,
|
|
31684
|
+
patch: {},
|
|
31685
|
+
fillIfUnset: { observerModelId: modelId, reflectorModelId: modelId }
|
|
31686
|
+
});
|
|
31687
|
+
return c.json({ ok: true, config: readStoredOMConfig(record) });
|
|
31688
|
+
} catch (error) {
|
|
31689
|
+
return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
|
|
31690
|
+
}
|
|
31691
|
+
}
|
|
31692
|
+
}),
|
|
31590
31693
|
// ── Observational memory ──────────────────────────────────────────────────
|
|
31591
|
-
// Mirrors the TUI's /om command. All five knobs are
|
|
31592
|
-
//
|
|
31593
|
-
//
|
|
31594
|
-
// settings.json. GET hydrates the session from the stored row first so the
|
|
31595
|
-
// DB, not the SDK's boot-time seed, is the source of truth.
|
|
31694
|
+
// Mirrors the TUI's /om command. All five knobs are durably stored in the
|
|
31695
|
+
// per-(org, user) `memory-settings` app table — never settings.json. When a
|
|
31696
|
+
// session is supplied, changes are also applied to its state and thread.
|
|
31596
31697
|
registerApiRoute7("/web/config/om", {
|
|
31597
31698
|
method: "GET",
|
|
31598
31699
|
requiresAuth: false,
|
|
31599
31700
|
handler: async (c) => {
|
|
31600
31701
|
const resourceId = c.req.query("resourceId");
|
|
31601
31702
|
const scope = c.req.query("scope") || void 0;
|
|
31602
|
-
if (!resourceId) return c.json({ error: "Missing required query param: resourceId" }, 400);
|
|
31603
31703
|
const context = await resolveMemorySettingsContext({
|
|
31604
31704
|
c: loose6(c),
|
|
31605
31705
|
auth,
|
|
@@ -31607,9 +31707,10 @@ var ConfigRoutes = class extends Route {
|
|
|
31607
31707
|
});
|
|
31608
31708
|
if ("response" in context) return context.response;
|
|
31609
31709
|
try {
|
|
31710
|
+
const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });
|
|
31711
|
+
if (!resourceId) return c.json({ config: readStoredOMConfig(record) });
|
|
31610
31712
|
const session = await controller.getSessionByResource?.(resourceId, scope);
|
|
31611
31713
|
if (!session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
|
|
31612
|
-
const record = await context.storage.get({ orgId: context.orgId, userId: context.userId });
|
|
31613
31714
|
await hydrateSessionMemorySettings(session, record);
|
|
31614
31715
|
return c.json({ config: readOMConfig(session) });
|
|
31615
31716
|
} catch (error) {
|
|
@@ -31634,7 +31735,6 @@ var ConfigRoutes = class extends Route {
|
|
|
31634
31735
|
const resourceId = typeof body.resourceId === "string" ? body.resourceId : "";
|
|
31635
31736
|
const scope = typeof body.scope === "string" && body.scope ? body.scope : void 0;
|
|
31636
31737
|
const modelId = typeof body.modelId === "string" ? body.modelId.trim() : "";
|
|
31637
|
-
if (!resourceId) return c.json({ error: "Missing required field: resourceId" }, 400);
|
|
31638
31738
|
if (!modelId) return c.json({ error: "Missing required field: modelId" }, 400);
|
|
31639
31739
|
const context = await resolveMemorySettingsContext({
|
|
31640
31740
|
c: loose6(c),
|
|
@@ -31643,18 +31743,19 @@ var ConfigRoutes = class extends Route {
|
|
|
31643
31743
|
});
|
|
31644
31744
|
if ("response" in context) return context.response;
|
|
31645
31745
|
try {
|
|
31646
|
-
const session = await controller.getSessionByResource?.(resourceId, scope);
|
|
31647
|
-
if (!session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
|
|
31648
|
-
const otherRole = role === "observer" ? session.om.reflector : session.om.observer;
|
|
31649
|
-
const otherRoleCurrentModelId = otherRole
|
|
31650
|
-
await session
|
|
31746
|
+
const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : void 0;
|
|
31747
|
+
if (resourceId && !session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
|
|
31748
|
+
const otherRole = session ? role === "observer" ? session.om.reflector : session.om.observer : void 0;
|
|
31749
|
+
const otherRoleCurrentModelId = otherRole?.modelId() ?? null;
|
|
31750
|
+
await session?.om[role].switchModel({ modelId });
|
|
31651
31751
|
const otherKey = role === "observer" ? "reflectorModelId" : "observerModelId";
|
|
31652
31752
|
await persistMemorySettings(
|
|
31653
31753
|
context,
|
|
31654
31754
|
{ [role === "observer" ? "observerModelId" : "reflectorModelId"]: modelId },
|
|
31655
31755
|
otherRoleCurrentModelId ? { [otherKey]: otherRoleCurrentModelId } : void 0
|
|
31656
31756
|
);
|
|
31657
|
-
|
|
31757
|
+
const config = session ? readOMConfig(session) : readStoredOMConfig(await context.storage.get({ orgId: context.orgId, userId: context.userId }));
|
|
31758
|
+
return c.json({ ok: true, config });
|
|
31658
31759
|
} catch (error) {
|
|
31659
31760
|
return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
|
|
31660
31761
|
}
|
|
@@ -31672,7 +31773,6 @@ var ConfigRoutes = class extends Route {
|
|
|
31672
31773
|
}
|
|
31673
31774
|
const resourceId = typeof body.resourceId === "string" ? body.resourceId : "";
|
|
31674
31775
|
const scope = typeof body.scope === "string" && body.scope ? body.scope : void 0;
|
|
31675
|
-
if (!resourceId) return c.json({ error: "Missing required field: resourceId" }, 400);
|
|
31676
31776
|
const observation = typeof body.observationThreshold === "number" && body.observationThreshold > 0 ? Math.round(body.observationThreshold) : void 0;
|
|
31677
31777
|
const reflection = typeof body.reflectionThreshold === "number" && body.reflectionThreshold > 0 ? Math.round(body.reflectionThreshold) : void 0;
|
|
31678
31778
|
if (observation === void 0 && reflection === void 0) {
|
|
@@ -31685,13 +31785,13 @@ var ConfigRoutes = class extends Route {
|
|
|
31685
31785
|
});
|
|
31686
31786
|
if ("response" in context) return context.response;
|
|
31687
31787
|
try {
|
|
31688
|
-
const session = await controller.getSessionByResource?.(resourceId, scope);
|
|
31689
|
-
if (!session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
|
|
31690
|
-
if (observation !== void 0) {
|
|
31788
|
+
const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : void 0;
|
|
31789
|
+
if (resourceId && !session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
|
|
31790
|
+
if (observation !== void 0 && session) {
|
|
31691
31791
|
await session.state.set({ observationThreshold: observation });
|
|
31692
31792
|
await session.thread.setSetting({ key: "observationThreshold", value: observation });
|
|
31693
31793
|
}
|
|
31694
|
-
if (reflection !== void 0) {
|
|
31794
|
+
if (reflection !== void 0 && session) {
|
|
31695
31795
|
await session.state.set({ reflectionThreshold: reflection });
|
|
31696
31796
|
await session.thread.setSetting({ key: "reflectionThreshold", value: reflection });
|
|
31697
31797
|
}
|
|
@@ -31699,7 +31799,8 @@ var ConfigRoutes = class extends Route {
|
|
|
31699
31799
|
...observation !== void 0 ? { observationThreshold: observation } : {},
|
|
31700
31800
|
...reflection !== void 0 ? { reflectionThreshold: reflection } : {}
|
|
31701
31801
|
});
|
|
31702
|
-
|
|
31802
|
+
const config = session ? readOMConfig(session) : readStoredOMConfig(await context.storage.get({ orgId: context.orgId, userId: context.userId }));
|
|
31803
|
+
return c.json({ ok: true, config });
|
|
31703
31804
|
} catch (error) {
|
|
31704
31805
|
return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
|
|
31705
31806
|
}
|
|
@@ -31717,7 +31818,6 @@ var ConfigRoutes = class extends Route {
|
|
|
31717
31818
|
}
|
|
31718
31819
|
const resourceId = typeof body.resourceId === "string" ? body.resourceId : "";
|
|
31719
31820
|
const scope = typeof body.scope === "string" && body.scope ? body.scope : void 0;
|
|
31720
|
-
if (!resourceId) return c.json({ error: "Missing required field: resourceId" }, 400);
|
|
31721
31821
|
const raw = body.value;
|
|
31722
31822
|
const value = raw === "auto" || raw === true || raw === false ? raw : "auto";
|
|
31723
31823
|
if (raw !== "auto" && raw !== true && raw !== false) {
|
|
@@ -31730,12 +31830,15 @@ var ConfigRoutes = class extends Route {
|
|
|
31730
31830
|
});
|
|
31731
31831
|
if ("response" in context) return context.response;
|
|
31732
31832
|
try {
|
|
31733
|
-
const session = await controller.getSessionByResource?.(resourceId, scope);
|
|
31734
|
-
if (!session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
|
|
31735
|
-
|
|
31736
|
-
|
|
31833
|
+
const session = resourceId ? await controller.getSessionByResource?.(resourceId, scope) : void 0;
|
|
31834
|
+
if (resourceId && !session) return c.json({ error: `No session for resourceId "${resourceId}"` }, 404);
|
|
31835
|
+
if (session) {
|
|
31836
|
+
await session.state.set({ observeAttachments: value });
|
|
31837
|
+
await session.thread.setSetting({ key: "observeAttachments", value });
|
|
31838
|
+
}
|
|
31737
31839
|
await persistMemorySettings(context, { observeAttachments: value });
|
|
31738
|
-
|
|
31840
|
+
const config = session ? readOMConfig(session) : readStoredOMConfig(await context.storage.get({ orgId: context.orgId, userId: context.userId }));
|
|
31841
|
+
return c.json({ ok: true, config });
|
|
31739
31842
|
} catch (error) {
|
|
31740
31843
|
return c.json({ error: error instanceof Error ? error.message : String(error) }, 500);
|
|
31741
31844
|
}
|
|
@@ -34778,7 +34881,7 @@ var WorkItemRoutes = class extends Route {
|
|
|
34778
34881
|
if (!project) {
|
|
34779
34882
|
return { response: c.json({ error: "Project not found" }, 404) };
|
|
34780
34883
|
}
|
|
34781
|
-
return { ...tenant, factoryProjectId: projectId };
|
|
34884
|
+
return { ...tenant, factoryProjectId: projectId, defaultModelId: project.defaultModelId };
|
|
34782
34885
|
}
|
|
34783
34886
|
/**
|
|
34784
34887
|
* Emit the audit events a successful work-item PATCH implies: always
|
|
@@ -35063,6 +35166,7 @@ var WorkItemRoutes = class extends Route {
|
|
|
35063
35166
|
const input = parseStartBody(await readJson2(loose10(c)), resolved, resolved.factoryProjectId);
|
|
35064
35167
|
if (!input) return c.json({ error: "invalid_factory_start" }, 400);
|
|
35065
35168
|
input.requestContext = loose10(c).get("requestContext");
|
|
35169
|
+
input.defaultModelId = resolved.defaultModelId ?? void 0;
|
|
35066
35170
|
if (!input.workItem.id && ((input.workItem.input.stages ?? ["intake"]).length !== 1 || (input.workItem.input.stages ?? ["intake"])[0] !== "intake")) {
|
|
35067
35171
|
return c.json(
|
|
35068
35172
|
{ error: "governed_transition_required", message: "Create the work item in Intake before starting it." },
|
|
@@ -35357,7 +35461,8 @@ function assembleFactoryApiRoutes(deps) {
|
|
|
35357
35461
|
deps.controller,
|
|
35358
35462
|
deps.domains.workItems,
|
|
35359
35463
|
transitionService,
|
|
35360
|
-
githubIntegration?.sourceControlStorage
|
|
35464
|
+
githubIntegration?.sourceControlStorage,
|
|
35465
|
+
deps.domains.memorySettings
|
|
35361
35466
|
) : void 0;
|
|
35362
35467
|
if (transitionService && startCoordinator) {
|
|
35363
35468
|
deps.onFactoryRuntime?.({
|
|
@@ -35514,7 +35619,9 @@ function pullRequestOpened(context) {
|
|
|
35514
35619
|
metadata: {
|
|
35515
35620
|
githubRepositoryId: context.repository.id,
|
|
35516
35621
|
githubPullRequestNumber: context.pullRequest.number,
|
|
35517
|
-
factoryAuthored: context.actor.type === "github" && context.actor.factoryAuthored
|
|
35622
|
+
factoryAuthored: context.actor.type === "github" && context.actor.factoryAuthored,
|
|
35623
|
+
headBranch: context.pullRequest.headBranch,
|
|
35624
|
+
baseBranch: context.pullRequest.baseBranch
|
|
35518
35625
|
}
|
|
35519
35626
|
};
|
|
35520
35627
|
}
|