@things-factory/ai-assistant 10.1.202 → 10.1.205
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/service/assistant-mode/index.d.ts +1 -1
- package/dist-server/service/assistant-mode/index.js.map +1 -1
- package/dist-server/service/assistant-mode/mode-categories.d.ts +10 -0
- package/dist-server/service/assistant-mode/mode-categories.js +10 -0
- package/dist-server/service/assistant-mode/mode-categories.js.map +1 -1
- package/dist-server/service/assistant-mode/types.d.ts +14 -0
- package/dist-server/service/assistant-mode/types.js.map +1 -1
- package/dist-server/service/index.d.ts +2 -1
- package/dist-server/service/index.js +4 -1
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/unattended-run/assistant-run.d.ts +45 -0
- package/dist-server/service/unattended-run/assistant-run.js +248 -0
- package/dist-server/service/unattended-run/assistant-run.js.map +1 -0
- package/dist-server/service/unattended-run/index.d.ts +8 -0
- package/dist-server/service/unattended-run/index.js +15 -0
- package/dist-server/service/unattended-run/index.js.map +1 -0
- package/dist-server/service/unattended-run/limits.d.ts +9 -0
- package/dist-server/service/unattended-run/limits.js +24 -0
- package/dist-server/service/unattended-run/limits.js.map +1 -0
- package/dist-server/service/unattended-run/run-as.d.ts +24 -0
- package/dist-server/service/unattended-run/run-as.js +26 -0
- package/dist-server/service/unattended-run/run-as.js.map +1 -0
- package/dist-server/service/unattended-run/run-budget.d.ts +24 -0
- package/dist-server/service/unattended-run/run-budget.js +46 -0
- package/dist-server/service/unattended-run/run-budget.js.map +1 -0
- package/dist-server/service/unattended-run/run-ledger.d.ts +13 -0
- package/dist-server/service/unattended-run/run-ledger.js +29 -0
- package/dist-server/service/unattended-run/run-ledger.js.map +1 -0
- package/dist-server/service/unattended-run/run-outcome.d.ts +9 -0
- package/dist-server/service/unattended-run/run-outcome.js +46 -0
- package/dist-server/service/unattended-run/run-outcome.js.map +1 -0
- package/dist-server/service/unattended-run/run-store.d.ts +31 -0
- package/dist-server/service/unattended-run/run-store.js +108 -0
- package/dist-server/service/unattended-run/run-store.js.map +1 -0
- package/dist-server/service/unattended-run/run-unattended.d.ts +50 -0
- package/dist-server/service/unattended-run/run-unattended.js +214 -0
- package/dist-server/service/unattended-run/run-unattended.js.map +1 -0
- package/dist-server/service/unattended-run/unattended-prompt.d.ts +3 -0
- package/dist-server/service/unattended-run/unattended-prompt.js +27 -0
- package/dist-server/service/unattended-run/unattended-prompt.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/server/service/assistant-mode/index.ts +1 -1
- package/server/service/assistant-mode/mode-categories.ts +10 -0
- package/server/service/assistant-mode/types.ts +15 -0
- package/server/service/index.ts +4 -1
- package/server/service/unattended-run/assistant-run.ts +199 -0
- package/server/service/unattended-run/index.ts +10 -0
- package/server/service/unattended-run/limits.ts +24 -0
- package/server/service/unattended-run/run-as.ts +38 -0
- package/server/service/unattended-run/run-budget.ts +58 -0
- package/server/service/unattended-run/run-ledger.ts +31 -0
- package/server/service/unattended-run/run-outcome.ts +43 -0
- package/server/service/unattended-run/run-store-race.pg.test.ts +83 -0
- package/server/service/unattended-run/run-store.ts +162 -0
- package/server/service/unattended-run/run-unattended.test.ts +477 -0
- package/server/service/unattended-run/run-unattended.ts +246 -0
- package/server/service/unattended-run/unattended-prompt.ts +24 -0
- package/translations/en.json +15 -1
- package/translations/es.json +15 -1
- package/translations/ja.json +15 -1
- package/translations/ko.json +15 -1
- package/translations/ms.json +15 -1
- package/translations/zh.json +15 -1
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
export { registerAssistantMode, getAssistantMode, listAssistantModes, assistantModeForSubject, getAssistantModeWarnings, clearAssistantModes } from './registry.js';
|
|
7
7
|
export { resolveModeSettings, assistantModeView } from './resolve.js';
|
|
8
8
|
export { ABSENCE_RULE, NEXT_REQUEST_RULE, conversationPrompt, splitNextRequest } from './screen-rules.js';
|
|
9
|
-
export type { AssistantModeSpec, AssistantModeSlash, AssistantModeWarning } from './types.js';
|
|
9
|
+
export type { AssistantModeSpec, AssistantModeSlash, AssistantModeWarning, UnattendedLimits } from './types.js';
|
|
10
10
|
export type { AssistantModeRef, ModeSettings, AssistantModeView, AssistantModeSlashView, Translate } from './resolve.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/assistant-mode/index.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,6CAOsB;AANpB,oHAAA,qBAAqB,OAAA;AACrB,+GAAA,gBAAgB,OAAA;AAChB,iHAAA,kBAAkB,OAAA;AAClB,sHAAA,uBAAuB,OAAA;AACvB,uHAAA,wBAAwB,OAAA;AACxB,kHAAA,mBAAmB,OAAA;AAErB,2CAAqE;AAA5D,iHAAA,mBAAmB,OAAA;AAAE,+GAAA,iBAAiB,OAAA;AAC/C,qDAAyG;AAAhG,+GAAA,YAAY,OAAA;AAAE,oHAAA,iBAAiB,OAAA;AAAE,qHAAA,kBAAkB,OAAA;AAAE,mHAAA,gBAAgB,OAAA","sourcesContent":["/**\n * Modes — what each conversation is, declared by the app server that owns the screen.\n *\n * Design: ADR-0061 decision 7 (`operato-application/adr/ADR-0061.md`) and the AI standard's A2.\n */\nexport {\n registerAssistantMode,\n getAssistantMode,\n listAssistantModes,\n assistantModeForSubject,\n getAssistantModeWarnings,\n clearAssistantModes\n} from './registry.js'\nexport { resolveModeSettings, assistantModeView } from './resolve.js'\nexport { ABSENCE_RULE, NEXT_REQUEST_RULE, conversationPrompt, splitNextRequest } from './screen-rules.js'\nexport type { AssistantModeSpec, AssistantModeSlash, AssistantModeWarning } from './types.js'\nexport type { AssistantModeRef, ModeSettings, AssistantModeView, AssistantModeSlashView, Translate } from './resolve.js'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/assistant-mode/index.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,6CAOsB;AANpB,oHAAA,qBAAqB,OAAA;AACrB,+GAAA,gBAAgB,OAAA;AAChB,iHAAA,kBAAkB,OAAA;AAClB,sHAAA,uBAAuB,OAAA;AACvB,uHAAA,wBAAwB,OAAA;AACxB,kHAAA,mBAAmB,OAAA;AAErB,2CAAqE;AAA5D,iHAAA,mBAAmB,OAAA;AAAE,+GAAA,iBAAiB,OAAA;AAC/C,qDAAyG;AAAhG,+GAAA,YAAY,OAAA;AAAE,oHAAA,iBAAiB,OAAA;AAAE,qHAAA,kBAAkB,OAAA;AAAE,mHAAA,gBAAgB,OAAA","sourcesContent":["/**\n * Modes — what each conversation is, declared by the app server that owns the screen.\n *\n * Design: ADR-0061 decision 7 (`operato-application/adr/ADR-0061.md`) and the AI standard's A2.\n */\nexport {\n registerAssistantMode,\n getAssistantMode,\n listAssistantModes,\n assistantModeForSubject,\n getAssistantModeWarnings,\n clearAssistantModes\n} from './registry.js'\nexport { resolveModeSettings, assistantModeView } from './resolve.js'\nexport { ABSENCE_RULE, NEXT_REQUEST_RULE, conversationPrompt, splitNextRequest } from './screen-rules.js'\nexport type { AssistantModeSpec, AssistantModeSlash, AssistantModeWarning, UnattendedLimits } from './types.js'\nexport type { AssistantModeRef, ModeSettings, AssistantModeView, AssistantModeSlashView, Translate } from './resolve.js'\n"]}
|
|
@@ -10,3 +10,13 @@ export declare function modeToolCategories(mode: {
|
|
|
10
10
|
entryTargets?: string[];
|
|
11
11
|
readTargets?: string[];
|
|
12
12
|
}): string[] | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* The categories an unattended run of a mode opens: its own and the lists it reads (design/ai/unattended-run.md §3).
|
|
15
|
+
*
|
|
16
|
+
* Not the 입력안 tools - nobody is there to press the card - nor the AI 작업판 or the attachment reader: there is no
|
|
17
|
+
* conversation for a card or a file to belong to.
|
|
18
|
+
*/
|
|
19
|
+
export declare function unattendedToolCategories(mode: {
|
|
20
|
+
toolCategories?: string[];
|
|
21
|
+
readTargets?: string[];
|
|
22
|
+
}): string[];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.modeToolCategories = modeToolCategories;
|
|
4
|
+
exports.unattendedToolCategories = unattendedToolCategories;
|
|
4
5
|
/* Pure - read by the resolver and by the boot report, so the report and the conversation open the same tools. */
|
|
5
6
|
/**
|
|
6
7
|
* The categories a mode opens: its own, the AI 작업판 (design/ai/workspace.md), the attachment reader when it
|
|
@@ -16,4 +17,13 @@ function modeToolCategories(mode) {
|
|
|
16
17
|
];
|
|
17
18
|
return [...new Set([...(mode.toolCategories ?? []), ...extra])];
|
|
18
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* The categories an unattended run of a mode opens: its own and the lists it reads (design/ai/unattended-run.md §3).
|
|
22
|
+
*
|
|
23
|
+
* Not the 입력안 tools - nobody is there to press the card - nor the AI 작업판 or the attachment reader: there is no
|
|
24
|
+
* conversation for a card or a file to belong to.
|
|
25
|
+
*/
|
|
26
|
+
function unattendedToolCategories(mode) {
|
|
27
|
+
return [...new Set([...(mode.toolCategories ?? []), ...(mode.readTargets ?? []).map(key => `data-read:${key}`)])];
|
|
28
|
+
}
|
|
19
29
|
//# sourceMappingURL=mode-categories.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mode-categories.js","sourceRoot":"","sources":["../../../server/service/assistant-mode/mode-categories.ts"],"names":[],"mappings":";;AAKA,gDASC;
|
|
1
|
+
{"version":3,"file":"mode-categories.js","sourceRoot":"","sources":["../../../server/service/assistant-mode/mode-categories.ts"],"names":[],"mappings":";;AAKA,gDASC;AAQD,4DAEC;AAxBD,iHAAiH;AACjH;;;GAGG;AACH,SAAgB,kBAAkB,CAAC,IAAwH;IACzJ,MAAM,KAAK,GAAG;QACZ,uFAAuF;QACvF,qBAAqB;QACrB,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,cAAc,GAAG,EAAE,CAAC;QAC5D,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC;KAC3D,CAAA;IACD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;AACjE,CAAC;AAED;;;;;GAKG;AACH,SAAgB,wBAAwB,CAAC,IAA2D;IAClG,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;AACnH,CAAC","sourcesContent":["/* Pure - read by the resolver and by the boot report, so the report and the conversation open the same tools. */\n/**\n * The categories a mode opens: its own, the AI 작업판 (design/ai/workspace.md), the attachment reader when it\n * takes files (design/ai/shared-dock.md §9-4), and one propose tool per record it may enter (design/ai/data-entry.md).\n */\nexport function modeToolCategories(mode: { toolCategories?: string[]; attachments?: { kinds?: string[] }; entryTargets?: string[]; readTargets?: string[] }): string[] | undefined {\n const extra = [\n /* Every conversation may put a large result on the AI 작업판 (design/ai/workspace.md). */\n 'assistant-workspace',\n ...(mode.attachments?.kinds?.length ? ['chat-attachments'] : []),\n ...(mode.entryTargets ?? []).map(key => `data-entry:${key}`),\n ...(mode.readTargets ?? []).map(key => `data-read:${key}`)\n ]\n return [...new Set([...(mode.toolCategories ?? []), ...extra])]\n}\n\n/**\n * The categories an unattended run of a mode opens: its own and the lists it reads (design/ai/unattended-run.md §3).\n *\n * Not the 입력안 tools - nobody is there to press the card - nor the AI 작업판 or the attachment reader: there is no\n * conversation for a card or a file to belong to.\n */\nexport function unattendedToolCategories(mode: { toolCategories?: string[]; readTargets?: string[] }): string[] {\n return [...new Set([...(mode.toolCategories ?? []), ...(mode.readTargets ?? []).map(key => `data-read:${key}`)])]\n}\n"]}
|
|
@@ -94,6 +94,20 @@ export interface AssistantModeSpec {
|
|
|
94
94
|
stagedNoticeKey?: string;
|
|
95
95
|
/** Follow-up chips for a proposal that arrived without its own. */
|
|
96
96
|
proposalChoices?: any[];
|
|
97
|
+
/**
|
|
98
|
+
* This mode may run with no person in it - a scheduled draft (design/ai/unattended-run.md §4). Absent: it may not.
|
|
99
|
+
* The limits are the mode's, as every limit is (ADR-0061 decision 7); the caller does not name them.
|
|
100
|
+
*/
|
|
101
|
+
unattended?: UnattendedLimits;
|
|
102
|
+
}
|
|
103
|
+
/** What one unattended run of a mode may spend. Each absent one takes the default in `unattended-run/limits.ts`. */
|
|
104
|
+
export interface UnattendedLimits {
|
|
105
|
+
/** Model requests of one run, the wrap-up included. */
|
|
106
|
+
maxModelCalls?: number;
|
|
107
|
+
/** Input and output tokens of one run together. The request that crosses it is the last one. */
|
|
108
|
+
maxTokens?: number;
|
|
109
|
+
/** Wall time of one run, model requests and tool calls together. */
|
|
110
|
+
timeoutMs?: number;
|
|
97
111
|
}
|
|
98
112
|
/** A declaration that registered but is not what the contract asks for. Code + params, not prose. */
|
|
99
113
|
export interface AssistantModeWarning {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../server/service/assistant-mode/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AttachmentPolicy } from '../chat-session/attachment-policy.js'\n/**\n * What a conversation is, declared by the app server that owns the screen (ADR-0061 decision 7).\n *\n * ADR-0058 put these five in one value so they could not fall out of step, but the value lived in\n * the browser and travelled on every request: the persona, the tool categories, the model and the\n * limits were the caller's to choose. A caller choosing its own tool categories is a caller\n * choosing its own authority, so the declaration moved here and the client sends only which one it\n * is talking in (`kind`) and what about (`target`).\n */\n\n/** A `/` sentence this mode offers, and what it needs to be answerable. */\nexport interface AssistantModeSlash {\n /** Short name shown in the list. */\n name: string\n /** i18n key for the one-line description. The server translates it into the request's locale. */\n descriptionKey: string\n /** i18n key for the sentence that lands in the input. */\n templateKey: string\n /**\n * The tools this sentence needs. A mode must not offer work it cannot do (ADR-0058 decision 3),\n * and a name outside `toolCategories` is reported at boot rather than when a person presses it.\n */\n tools?: string[]\n}\n\nexport interface AssistantModeSpec {\n /** `<app>.<surface>` — `twin.space`, `plant.station`, `figure.modeller`. */\n kind: string\n\n /**\n * Which kinds of subject this conversation is for — `['board']`, `['space']`.\n *\n * A screen says what it is showing (`context.subject`) and opens the one conversation for it: a screen has one\n * conversation (design/ai/screen-pattern.md §3). A list of types, so it can be counted at boot and pinned by a\n * test; two modes naming one subject is a boot warning.\n */\n subjects?: string[]\n\n /** i18n key for what this conversation is called in the conversation list. */\n labelKey?: string\n /** Who the assistant is here, and what it must not claim to do. The server's, not the caller's. */\n systemPrompt: string\n /** Which tool categories this conversation may use. Absent or empty exposes none. */\n toolCategories?: string[]\n /** Make the model read before it answers — for surfaces whose subject is live state. */\n requireToolOnFirstTurn?: boolean\n /** Limits are policy, not a request field. The model is the domain's AI agent's (design/ai/agent-settings.md). */\n temperature?: number\n maxTokens?: number\n /** What `/` offers. Declared as keys; the server translates. */\n slashTemplates?: AssistantModeSlash[]\n /** What `@` offers. */\n catalogEntries?: any[]\n /**\n * i18n key for the words in the empty input.\n *\n * The screen says what this conversation is for, and that differs by mode: figure's modeller had\n * \"describe the figure you want\" while the person was there to change the figure already open.\n */\n placeholderKey?: string\n\n /**\n * 빈 대화가 무엇을 말하는가 — 제목과 한 줄 (ADR-0061 결정 7).\n *\n * 자리표와 `/` 는 대화를 따라가는데 이 블록만 host 속성에 남아 있었다. 그래서 머리에는 「이 도형\n * 고치기」가 서 있고 본문은 「만들 Figure 를 설명하세요」라고 적혀 있었다(2026-09-18, Figure 레인\n * :3300). 한 대화가 화면에 무엇을 말하는가는 한 자리에서 나와야 한다.\n */\n introKeys?: { title: string; subtitle: string }\n\n /**\n * 빈 대화의 예시 — 「이 대화에서 할 수 있는 말」.\n *\n * 예시는 그 도구로 **실제로 할 수 있는 말**이어야 한다. 할 수 없는 것을 예시로 두면 빈 화면이 거짓을\n * 가르친다. 대화마다 열리는 도구가 다르므로 예시도 대화를 따라간다.\n */\n exampleKeys?: Array<{ labelKey: string; itemKeys: string[] }>\n\n /**\n * What this conversation accepts as attachments (design/ai/shared-dock.md §9-1). Absent: nothing - the\n * screen offers no attach button, so no file is taken that the model would never see.\n */\n attachments?: AttachmentPolicy\n /**\n * Which records this conversation may enter from material (design/ai/data-entry.md) - keys registered\n * with `registerEntryTarget`. Each opens that target's propose tool; its door still decides who gets it.\n */\n entryTargets?: string[]\n /** The lists of the application the conversation may read - read targets by key (design/ai/read-targets.md). */\n readTargets?: string[]\n /** i18n key for the line under an empty conversation. */\n footerNoticeKey?: string\n /** i18n key for the line shown once the host reports a proposal staged. */\n stagedNoticeKey?: string\n /** Follow-up chips for a proposal that arrived without its own. */\n proposalChoices?: any[]\n}\n\n/** A declaration that registered but is not what the contract asks for. Code + params, not prose. */\nexport interface AssistantModeWarning {\n /**\n * `assistant-mode-slash-outside-tools` — a `/` sentence needs a tool this mode does not open.\n * `assistant-mode-subject-claimed-twice` — two conversations name the same subject type.\n * `assistant-mode-entry-target-unknown` — a record the mode enters that no application registered.\n */\n code: 'assistant-mode-slash-outside-tools' | 'assistant-mode-subject-claimed-twice' | 'assistant-mode-entry-target-unknown'\n params: { kind: string; slash?: string; tool?: string; subject?: string; kinds?: string[]; target?: string }\n /** For a person reading the boot log; callers act on the code and params. */\n message: string\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../server/service/assistant-mode/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AttachmentPolicy } from '../chat-session/attachment-policy.js'\n/**\n * What a conversation is, declared by the app server that owns the screen (ADR-0061 decision 7).\n *\n * ADR-0058 put these five in one value so they could not fall out of step, but the value lived in\n * the browser and travelled on every request: the persona, the tool categories, the model and the\n * limits were the caller's to choose. A caller choosing its own tool categories is a caller\n * choosing its own authority, so the declaration moved here and the client sends only which one it\n * is talking in (`kind`) and what about (`target`).\n */\n\n/** A `/` sentence this mode offers, and what it needs to be answerable. */\nexport interface AssistantModeSlash {\n /** Short name shown in the list. */\n name: string\n /** i18n key for the one-line description. The server translates it into the request's locale. */\n descriptionKey: string\n /** i18n key for the sentence that lands in the input. */\n templateKey: string\n /**\n * The tools this sentence needs. A mode must not offer work it cannot do (ADR-0058 decision 3),\n * and a name outside `toolCategories` is reported at boot rather than when a person presses it.\n */\n tools?: string[]\n}\n\nexport interface AssistantModeSpec {\n /** `<app>.<surface>` — `twin.space`, `plant.station`, `figure.modeller`. */\n kind: string\n\n /**\n * Which kinds of subject this conversation is for — `['board']`, `['space']`.\n *\n * A screen says what it is showing (`context.subject`) and opens the one conversation for it: a screen has one\n * conversation (design/ai/screen-pattern.md §3). A list of types, so it can be counted at boot and pinned by a\n * test; two modes naming one subject is a boot warning.\n */\n subjects?: string[]\n\n /** i18n key for what this conversation is called in the conversation list. */\n labelKey?: string\n /** Who the assistant is here, and what it must not claim to do. The server's, not the caller's. */\n systemPrompt: string\n /** Which tool categories this conversation may use. Absent or empty exposes none. */\n toolCategories?: string[]\n /** Make the model read before it answers — for surfaces whose subject is live state. */\n requireToolOnFirstTurn?: boolean\n /** Limits are policy, not a request field. The model is the domain's AI agent's (design/ai/agent-settings.md). */\n temperature?: number\n maxTokens?: number\n /** What `/` offers. Declared as keys; the server translates. */\n slashTemplates?: AssistantModeSlash[]\n /** What `@` offers. */\n catalogEntries?: any[]\n /**\n * i18n key for the words in the empty input.\n *\n * The screen says what this conversation is for, and that differs by mode: figure's modeller had\n * \"describe the figure you want\" while the person was there to change the figure already open.\n */\n placeholderKey?: string\n\n /**\n * 빈 대화가 무엇을 말하는가 — 제목과 한 줄 (ADR-0061 결정 7).\n *\n * 자리표와 `/` 는 대화를 따라가는데 이 블록만 host 속성에 남아 있었다. 그래서 머리에는 「이 도형\n * 고치기」가 서 있고 본문은 「만들 Figure 를 설명하세요」라고 적혀 있었다(2026-09-18, Figure 레인\n * :3300). 한 대화가 화면에 무엇을 말하는가는 한 자리에서 나와야 한다.\n */\n introKeys?: { title: string; subtitle: string }\n\n /**\n * 빈 대화의 예시 — 「이 대화에서 할 수 있는 말」.\n *\n * 예시는 그 도구로 **실제로 할 수 있는 말**이어야 한다. 할 수 없는 것을 예시로 두면 빈 화면이 거짓을\n * 가르친다. 대화마다 열리는 도구가 다르므로 예시도 대화를 따라간다.\n */\n exampleKeys?: Array<{ labelKey: string; itemKeys: string[] }>\n\n /**\n * What this conversation accepts as attachments (design/ai/shared-dock.md §9-1). Absent: nothing - the\n * screen offers no attach button, so no file is taken that the model would never see.\n */\n attachments?: AttachmentPolicy\n /**\n * Which records this conversation may enter from material (design/ai/data-entry.md) - keys registered\n * with `registerEntryTarget`. Each opens that target's propose tool; its door still decides who gets it.\n */\n entryTargets?: string[]\n /** The lists of the application the conversation may read - read targets by key (design/ai/read-targets.md). */\n readTargets?: string[]\n /** i18n key for the line under an empty conversation. */\n footerNoticeKey?: string\n /** i18n key for the line shown once the host reports a proposal staged. */\n stagedNoticeKey?: string\n /** Follow-up chips for a proposal that arrived without its own. */\n proposalChoices?: any[]\n /**\n * This mode may run with no person in it - a scheduled draft (design/ai/unattended-run.md §4). Absent: it may not.\n * The limits are the mode's, as every limit is (ADR-0061 decision 7); the caller does not name them.\n */\n unattended?: UnattendedLimits\n}\n\n/** What one unattended run of a mode may spend. Each absent one takes the default in `unattended-run/limits.ts`. */\nexport interface UnattendedLimits {\n /** Model requests of one run, the wrap-up included. */\n maxModelCalls?: number\n /** Input and output tokens of one run together. The request that crosses it is the last one. */\n maxTokens?: number\n /** Wall time of one run, model requests and tool calls together. */\n timeoutMs?: number\n}\n\n/** A declaration that registered but is not what the contract asks for. Code + params, not prose. */\nexport interface AssistantModeWarning {\n /**\n * `assistant-mode-slash-outside-tools` — a `/` sentence needs a tool this mode does not open.\n * `assistant-mode-subject-claimed-twice` — two conversations name the same subject type.\n * `assistant-mode-entry-target-unknown` — a record the mode enters that no application registered.\n */\n code: 'assistant-mode-slash-outside-tools' | 'assistant-mode-subject-claimed-twice' | 'assistant-mode-entry-target-unknown'\n params: { kind: string; slash?: string; tool?: string; subject?: string; kinds?: string[]; target?: string }\n /** For a person reading the boot log; callers act on the code and params. */\n message: string\n}\n"]}
|
|
@@ -43,7 +43,8 @@ export * from './chat-session-participant/mention-invite.js';
|
|
|
43
43
|
export * from './chat-session-participant/presence.js';
|
|
44
44
|
export * from './chat-message/index.js';
|
|
45
45
|
export * from './chat-session-participant/index.js';
|
|
46
|
-
export
|
|
46
|
+
export * from './unattended-run/index.js';
|
|
47
|
+
export declare const entities: (typeof import("./chat-message/chat-message.js").ChatMessage | typeof import("./chat-session/chat-session.js").ChatSession | typeof import("./chat-session-participant/chat-session-participant.js").ChatSessionParticipant | typeof import("./unattended-run/assistant-run.js").AssistantRun)[];
|
|
47
48
|
export declare const schema: {
|
|
48
49
|
resolverClasses: (typeof ChatSessionResolver | typeof AssistantChatResolver | typeof AssistantModeResolver | typeof AssistantCapabilityResolver | typeof AiAgentResolver | typeof MySessionActivitySubscription | typeof ChatMessageSubscription | typeof EntryProposalResolver)[];
|
|
49
50
|
};
|
|
@@ -17,6 +17,7 @@ require("./chat-session/session-purge.js");
|
|
|
17
17
|
require("./chat-session/attachment-route.js");
|
|
18
18
|
const entry_resolver_js_1 = require("./data-entry/entry-resolver.js");
|
|
19
19
|
require("./workspace/workspace-tools.js");
|
|
20
|
+
const index_js_4 = require("./unattended-run/index.js");
|
|
20
21
|
tslib_1.__exportStar(require("./types.js"), exports);
|
|
21
22
|
tslib_1.__exportStar(require("./chat-session-resolver.js"), exports);
|
|
22
23
|
tslib_1.__exportStar(require("./assistant-chat-resolver.js"), exports);
|
|
@@ -71,7 +72,9 @@ tslib_1.__exportStar(require("./chat-session-participant/mention-invite.js"), ex
|
|
|
71
72
|
tslib_1.__exportStar(require("./chat-session-participant/presence.js"), exports);
|
|
72
73
|
tslib_1.__exportStar(require("./chat-message/index.js"), exports);
|
|
73
74
|
tslib_1.__exportStar(require("./chat-session-participant/index.js"), exports);
|
|
74
|
-
|
|
75
|
+
/* A mode run with no person in it - a scheduled draft (operato-application/design/ai/unattended-run.md). */
|
|
76
|
+
tslib_1.__exportStar(require("./unattended-run/index.js"), exports);
|
|
77
|
+
exports.entities = [...index_js_1.entities, ...index_js_2.entities, ...index_js_3.entities, ...index_js_4.entities];
|
|
75
78
|
exports.schema = {
|
|
76
79
|
resolverClasses: [
|
|
77
80
|
chat_session_resolver_js_1.ChatSessionResolver,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,yEAAgE;AAChE,6EAAoE;AACpE,4FAAmF;AACnF,yFAAgF;AAChF,iEAAwD;AACxD,sGAA+F;AAC/F,8FAAqF;AACrF,sDAAyE;AACzE,sDAAyE;AACzE,kEAAgG;AAChG,8CAA2C;AAC3C,2CAAwC;AACxC,8CAA2C;AAC3C,sEAAsE;AACtE,0CAAuC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;AAAA,yEAAgE;AAChE,6EAAoE;AACpE,4FAAmF;AACnF,yFAAgF;AAChF,iEAAwD;AACxD,sGAA+F;AAC/F,8FAAqF;AACrF,sDAAyE;AACzE,sDAAyE;AACzE,kEAAgG;AAChG,8CAA2C;AAC3C,2CAAwC;AACxC,8CAA2C;AAC3C,sEAAsE;AACtE,0CAAuC;AACvC,wDAA6E;AAE7E,qDAA0B;AAC1B,qEAA0C;AAC1C,uEAA4C;AAC5C,oGAAoG;AACpG,oEAAyC;AACzC,iEAA2D;AAAlD,0HAAA,iBAAiB,OAAA;AAC1B,6EAAkD;AAClD;;;GAGG;AACH,2DAAgC;AAChC,+GAA+G;AAC/G,uEAA4C;AAC5C,8DAAkF;AAAzE,qHAAA,mBAAmB,OAAA;AAAE,iHAAA,eAAe,OAAA;AAC7C,uHAAuH;AACvH,qEAA0C;AAC1C,2DAAoH;AAA3G,mHAAA,kBAAkB,OAAA;AAAE,+GAAA,cAAc,OAAA;AAAE,mHAAA,kBAAkB,OAAA;AAAE,iHAAA,gBAAgB,OAAA;AACjF,mEAAwC;AACxC,iFAAiF;AACjF,0EAA+C;AAC/C,gDAAgD;AAChD,iEAAsC;AACtC,sDAAsD;AACtD,2EAAgD;AAChD,gHAAgH;AAChH,+EAAoD;AACpD,kEAAuC;AACvC,8DAA8D;AAC9D,0EAA+C;AAC/C,8EAAmD;AACnD,0EAA+C;AAC/C,qFAA0D;AAC1D,uFAA4D;AAC5D,wEAA6C;AAC7C,4EAAiD;AACjD,yEAA8C;AAC9C,wDAAwD;AACxD,iFAAsD;AACtD,iFAAsD;AACtD,mFAAwD;AACxD,4FAAiE;AACjE,2DAA2D;AAC3D,uFAA4D;AAC5D,iFAAsD;AACtD,kEAAuC;AACvC,8EAAmD;AACnD,4GAA4G;AAC5G,oEAAyC;AAE5B,QAAA,QAAQ,GAAG,CAAC,GAAG,mBAAmB,EAAE,GAAG,mBAAmB,EAAE,GAAG,mBAA8B,EAAE,GAAG,mBAAqB,CAAC,CAAA;AAExH,QAAA,MAAM,GAAG;IACpB,eAAe,EAAE;QACf,8CAAmB;QACnB,sDAAsD;QACtD,kDAAqB;QACrB,uDAAuD;QACvD,kDAAqB;QACrB,wDAAwD;QACxD,8DAA2B;QAC3B,mGAAmG;QACnG,sCAAe;QACf,sDAAuB;QACvB,qDAAqD;QACrD,gEAA6B;QAC7B,mDAAmD;QACnD,yCAAqB;KACtB;CACF,CAAA","sourcesContent":["import { ChatSessionResolver } from './chat-session-resolver.js'\nimport { AssistantChatResolver } from './assistant-chat-resolver.js'\nimport { AssistantModeResolver } from './assistant-mode/assistant-mode-resolver.js'\nimport { AssistantCapabilityResolver } from './assistant-capability-resolver.js'\nimport { AiAgentResolver } from './ai-agent-resolver.js'\nimport { MySessionActivitySubscription } from './chat-session/session-activity-subscription.js'\nimport { ChatMessageSubscription } from './chat-message/chat-message-subscription.js'\nimport { entities as ChatSessionEntities } from './chat-session/index.js'\nimport { entities as ChatMessageEntities } from './chat-message/index.js'\nimport { entities as ChatSessionParticipantEntities } from './chat-session-participant/index.js'\nimport './chat-session/attachment-tools.js'\nimport './chat-session/session-purge.js'\nimport './chat-session/attachment-route.js'\nimport { EntryProposalResolver } from './data-entry/entry-resolver.js'\nimport './workspace/workspace-tools.js'\nimport { entities as UnattendedRunEntities } from './unattended-run/index.js'\n\nexport * from './types.js'\nexport * from './chat-session-resolver.js'\nexport * from './assistant-chat-resolver.js'\n/* The mode registry — each app server declares what its conversations are (ADR-0061 decision 7). */\nexport * from './assistant-mode/index.js'\nexport { requestTranslator } from './request-translator.js'\nexport * from './assistant-capability-resolver.js'\n/*\n * 대화 각본 하네스는 **런타임 export 에서 뺀다**(ADR-0070 A15 결정 ④) — 시험 도구가 서버 번들에\n * 실린다. 시험은 경로로 가져온다: `…/service/testing/conversation-script.js`.\n */\nexport * from './tool-access.js'\n/* Data entry from material - an app registers what it can enter; a mode names it (design/ai/data-entry.md). */\nexport * from './data-entry/entry-target.js'\nexport { registerEntryTarget, entryCategoryOf } from './data-entry/entry-tools.js'\n/* Reading an application's lists - an app registers what it lets read; a mode names it (design/ai/read-targets.md). */\nexport * from './data-read/read-target.js'\nexport { registerReadTarget, readCategoryOf, registerDetailRead, detailCategoryOf } from './data-read/read-tools.js'\nexport * from './data-read/list-read.js'\n/* The AI 작업판 - large results on a page of their own (design/ai/workspace.md). */\nexport * from './workspace/workspace-blocks.js'\n/* 무엇이 근거인가 — 도구 결과 밖의 셋(프롬프트 · 대화 · 화면 스냅숏). */\nexport * from './grounding-sources.js'\n/* 앵커 순수 로직 — 호스트가 앵커 종류를 참조한다(리졸버는 데코레이터 때문에 무겁다). */\nexport * from './chat-session/session-anchor.js'\n/* Who may read a conversation — one rule, also asked by doors outside this package (board-ai's revertPatch). */\nexport * from './chat-session/session-visibility.js'\nexport * from './chat-session/index.js'\n/* 순수 로직들 — 호스트(board-ai 등)가 같은 규칙을 쓰라고 공개한다. 베끼면 한쪽만 고쳐진다. */\nexport * from './chat-session/session-inbox.js'\nexport * from './chat-session/attachment-policy.js'\nexport * from './chat-session/session-purge.js'\nexport * from './chat-session/session-activity-publish.js'\nexport * from './chat-session/session-activity-broadcast.js'\nexport * from './chat-message/llm-history.js'\nexport * from './chat-message/history-summary.js'\nexport * from './chat-message/fold-history.js'\n/* 상한 밖으로 밀려난 앞부분을 요약으로 접는 orchestration — 중립 문이 부른다. */\nexport * from './chat-message/fold-session-history.js'\nexport * from './chat-message/chat-message-publish.js'\nexport * from './chat-message/chat-message-broadcast.js'\nexport * from './chat-session-participant/invite-notification.js'\n/* 멘션이 사람을 불러들이는 자리 — 사람의 말을 저장하는 문만 부른다(ADR-0071 결정 1). */\nexport * from './chat-session-participant/mention-invite.js'\nexport * from './chat-session-participant/presence.js'\nexport * from './chat-message/index.js'\nexport * from './chat-session-participant/index.js'\n/* A mode run with no person in it - a scheduled draft (operato-application/design/ai/unattended-run.md). */\nexport * from './unattended-run/index.js'\n\nexport const entities = [...ChatSessionEntities, ...ChatMessageEntities, ...ChatSessionParticipantEntities, ...UnattendedRunEntities]\n\nexport const schema = {\n resolverClasses: [\n ChatSessionResolver,\n /* 문서를 갖지 않은 표면의 대화 — board 를 안 싣는 제품이 물어볼 수 있는 자리. */\n AssistantChatResolver,\n /* 화면이 자기 대화가 무엇을 주는지 묻는 자리 — 문구는 서버가 요청 로케일로 옮겨 낸다. */\n AssistantModeResolver,\n /* 「이 배포에 AI 가 있나 · 무엇이 선언 없이 등록됐나」 — 창구 하나(표준 A7-a). */\n AssistantCapabilityResolver,\n /* A domain's AI agents - the settings card and the dock's picker (design/ai/agent-settings.md). */\n AiAgentResolver,\n ChatMessageSubscription,\n /* 내가 참여한 모든 세션의 활동 — 창을 닫아 둔 표면이 배지·목록을 갱신할 수 있게. */\n MySessionActivitySubscription,\n /* 사람이 누른 입력 제안을 쓰는 자리 — 행마다 앱의 코드로, 그 사람의 권한으로. */\n EntryProposalResolver\n ]\n}\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Domain } from '@things-factory/shell';
|
|
2
|
+
import { User } from '@things-factory/auth-base';
|
|
3
|
+
export declare class AssistantRun {
|
|
4
|
+
readonly id?: string;
|
|
5
|
+
domain?: Domain;
|
|
6
|
+
domainId?: string;
|
|
7
|
+
name: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
source: string;
|
|
10
|
+
subject: string;
|
|
11
|
+
scheduledAt: Date;
|
|
12
|
+
modeKind: string;
|
|
13
|
+
modeTarget?: string;
|
|
14
|
+
runAs?: User;
|
|
15
|
+
runAsId?: string;
|
|
16
|
+
status: string;
|
|
17
|
+
attempt: number;
|
|
18
|
+
startedAt?: Date;
|
|
19
|
+
deadlineAt?: Date;
|
|
20
|
+
finishedAt?: Date;
|
|
21
|
+
draft?: string;
|
|
22
|
+
/** Each call of the run as the audit digests it (`ToolCallRecord`, never raw values), as JSON. */
|
|
23
|
+
reads?: string;
|
|
24
|
+
get readsJson(): any;
|
|
25
|
+
doors?: string[];
|
|
26
|
+
outcomeCode?: string;
|
|
27
|
+
outcomeParams?: string;
|
|
28
|
+
get outcomeParamsJson(): any;
|
|
29
|
+
/** The earlier attempts' endings, `[{ attempt, status, outcomeCode, startedAt, finishedAt }]`, as JSON. */
|
|
30
|
+
attempts?: string;
|
|
31
|
+
get attemptsJson(): any;
|
|
32
|
+
groundingWarnings?: string;
|
|
33
|
+
agentId?: string;
|
|
34
|
+
clientId?: string;
|
|
35
|
+
modelCalls: number;
|
|
36
|
+
inputTokens: number;
|
|
37
|
+
outputTokens: number;
|
|
38
|
+
cardsDropped: number;
|
|
39
|
+
creator?: User;
|
|
40
|
+
creatorId?: string;
|
|
41
|
+
updater?: User;
|
|
42
|
+
updaterId?: string;
|
|
43
|
+
createdAt?: Date;
|
|
44
|
+
updatedAt?: Date;
|
|
45
|
+
}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AssistantRun = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
/**
|
|
6
|
+
* AssistantRun — one occurrence of a mode run with no person in it, and what it left (design/ai/unattended-run.md).
|
|
7
|
+
*
|
|
8
|
+
* The one place the facts of an AI run are kept: its attempts, its state, the draft, the reads the draft rested on,
|
|
9
|
+
* what it spent and the doors behind it. The application that scheduled it keeps its own facts and points here by
|
|
10
|
+
* (source, subject, scheduledAt) or by id - it does not copy these (chief architect ruling, 2026-10-20).
|
|
11
|
+
*/
|
|
12
|
+
const typeorm_1 = require("typeorm");
|
|
13
|
+
const type_graphql_1 = require("type-graphql");
|
|
14
|
+
const graphql_scalars_1 = require("graphql-scalars");
|
|
15
|
+
const shell_1 = require("@things-factory/shell");
|
|
16
|
+
const auth_base_1 = require("@things-factory/auth-base");
|
|
17
|
+
const env_1 = require("@things-factory/env");
|
|
18
|
+
const ORMCONFIG = env_1.config.get('ormconfig', {});
|
|
19
|
+
const DATABASE_TYPE = ORMCONFIG.type;
|
|
20
|
+
const LONG_TEXT = {
|
|
21
|
+
type: DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
|
|
22
|
+
? 'longtext'
|
|
23
|
+
: DATABASE_TYPE == 'oracle'
|
|
24
|
+
? 'clob'
|
|
25
|
+
: DATABASE_TYPE == 'mssql'
|
|
26
|
+
? 'nvarchar'
|
|
27
|
+
: 'text',
|
|
28
|
+
length: DATABASE_TYPE == 'mssql' ? 'MAX' : undefined,
|
|
29
|
+
nullable: true
|
|
30
|
+
};
|
|
31
|
+
const parsed = (text) => {
|
|
32
|
+
if (!text)
|
|
33
|
+
return null;
|
|
34
|
+
try {
|
|
35
|
+
return JSON.parse(text);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
let AssistantRun = class AssistantRun {
|
|
42
|
+
get readsJson() {
|
|
43
|
+
return parsed(this.reads);
|
|
44
|
+
}
|
|
45
|
+
get outcomeParamsJson() {
|
|
46
|
+
return parsed(this.outcomeParams);
|
|
47
|
+
}
|
|
48
|
+
get attemptsJson() {
|
|
49
|
+
return parsed(this.attempts);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
exports.AssistantRun = AssistantRun;
|
|
53
|
+
tslib_1.__decorate([
|
|
54
|
+
(0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
|
|
55
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.ID, { description: 'Run id.' }),
|
|
56
|
+
tslib_1.__metadata("design:type", String)
|
|
57
|
+
], AssistantRun.prototype, "id", void 0);
|
|
58
|
+
tslib_1.__decorate([
|
|
59
|
+
(0, typeorm_1.ManyToOne)(type => shell_1.Domain),
|
|
60
|
+
(0, type_graphql_1.Field)(type => shell_1.Domain, { nullable: true, description: 'The domain the run is in.' }),
|
|
61
|
+
tslib_1.__metadata("design:type", shell_1.Domain)
|
|
62
|
+
], AssistantRun.prototype, "domain", void 0);
|
|
63
|
+
tslib_1.__decorate([
|
|
64
|
+
(0, typeorm_1.RelationId)((run) => run.domain),
|
|
65
|
+
tslib_1.__metadata("design:type", String)
|
|
66
|
+
], AssistantRun.prototype, "domainId", void 0);
|
|
67
|
+
tslib_1.__decorate([
|
|
68
|
+
(0, typeorm_1.Column)(),
|
|
69
|
+
(0, type_graphql_1.Field)({ description: 'Readable name of the occurrence - source, subject and time.' }),
|
|
70
|
+
tslib_1.__metadata("design:type", String)
|
|
71
|
+
], AssistantRun.prototype, "name", void 0);
|
|
72
|
+
tslib_1.__decorate([
|
|
73
|
+
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
|
74
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Description.' }),
|
|
75
|
+
tslib_1.__metadata("design:type", String)
|
|
76
|
+
], AssistantRun.prototype, "description", void 0);
|
|
77
|
+
tslib_1.__decorate([
|
|
78
|
+
(0, typeorm_1.Column)({ length: 64 }),
|
|
79
|
+
(0, type_graphql_1.Field)({ description: "Who scheduled it - '<app>.<work>', e.g. 'office.strategy-review'." }),
|
|
80
|
+
tslib_1.__metadata("design:type", String)
|
|
81
|
+
], AssistantRun.prototype, "source", void 0);
|
|
82
|
+
tslib_1.__decorate([
|
|
83
|
+
(0, typeorm_1.Column)({ length: 64 }),
|
|
84
|
+
(0, type_graphql_1.Field)({ description: "What it is about in the source's terms, e.g. a policy id." }),
|
|
85
|
+
tslib_1.__metadata("design:type", String)
|
|
86
|
+
], AssistantRun.prototype, "subject", void 0);
|
|
87
|
+
tslib_1.__decorate([
|
|
88
|
+
(0, typeorm_1.Column)(),
|
|
89
|
+
(0, type_graphql_1.Field)({ description: 'The occurrence this run is.' }),
|
|
90
|
+
tslib_1.__metadata("design:type", Date)
|
|
91
|
+
], AssistantRun.prototype, "scheduledAt", void 0);
|
|
92
|
+
tslib_1.__decorate([
|
|
93
|
+
(0, typeorm_1.Column)({ length: 64 }),
|
|
94
|
+
(0, type_graphql_1.Field)({ description: 'The assistant mode that ran.' }),
|
|
95
|
+
tslib_1.__metadata("design:type", String)
|
|
96
|
+
], AssistantRun.prototype, "modeKind", void 0);
|
|
97
|
+
tslib_1.__decorate([
|
|
98
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
99
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'What the mode was about.' }),
|
|
100
|
+
tslib_1.__metadata("design:type", String)
|
|
101
|
+
], AssistantRun.prototype, "modeTarget", void 0);
|
|
102
|
+
tslib_1.__decorate([
|
|
103
|
+
(0, typeorm_1.ManyToOne)(type => auth_base_1.User),
|
|
104
|
+
(0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true, description: 'The person the run acted as - its privileges and doors were theirs.' }),
|
|
105
|
+
tslib_1.__metadata("design:type", auth_base_1.User)
|
|
106
|
+
], AssistantRun.prototype, "runAs", void 0);
|
|
107
|
+
tslib_1.__decorate([
|
|
108
|
+
(0, typeorm_1.RelationId)((run) => run.runAs),
|
|
109
|
+
tslib_1.__metadata("design:type", String)
|
|
110
|
+
], AssistantRun.prototype, "runAsId", void 0);
|
|
111
|
+
tslib_1.__decorate([
|
|
112
|
+
(0, typeorm_1.Column)({ length: 16 }),
|
|
113
|
+
(0, type_graphql_1.Field)({ description: "'running' | 'succeeded' | 'failed' | 'refused'." }),
|
|
114
|
+
tslib_1.__metadata("design:type", String)
|
|
115
|
+
], AssistantRun.prototype, "status", void 0);
|
|
116
|
+
tslib_1.__decorate([
|
|
117
|
+
(0, typeorm_1.Column)({ type: 'int', default: 1 }),
|
|
118
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'Which attempt at this occurrence the row holds, from 1.' }),
|
|
119
|
+
tslib_1.__metadata("design:type", Number)
|
|
120
|
+
], AssistantRun.prototype, "attempt", void 0);
|
|
121
|
+
tslib_1.__decorate([
|
|
122
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
123
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'When this attempt started.' }),
|
|
124
|
+
tslib_1.__metadata("design:type", Date)
|
|
125
|
+
], AssistantRun.prototype, "startedAt", void 0);
|
|
126
|
+
tslib_1.__decorate([
|
|
127
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
128
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Past this a running attempt is taken as gone and the next call takes the occurrence over.' }),
|
|
129
|
+
tslib_1.__metadata("design:type", Date)
|
|
130
|
+
], AssistantRun.prototype, "deadlineAt", void 0);
|
|
131
|
+
tslib_1.__decorate([
|
|
132
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
133
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'When this attempt ended.' }),
|
|
134
|
+
tslib_1.__metadata("design:type", Date)
|
|
135
|
+
], AssistantRun.prototype, "finishedAt", void 0);
|
|
136
|
+
tslib_1.__decorate([
|
|
137
|
+
(0, typeorm_1.Column)(LONG_TEXT),
|
|
138
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The draft - only when the run succeeded.' }),
|
|
139
|
+
tslib_1.__metadata("design:type", String)
|
|
140
|
+
], AssistantRun.prototype, "draft", void 0);
|
|
141
|
+
tslib_1.__decorate([
|
|
142
|
+
(0, typeorm_1.Column)(LONG_TEXT),
|
|
143
|
+
tslib_1.__metadata("design:type", String)
|
|
144
|
+
], AssistantRun.prototype, "reads", void 0);
|
|
145
|
+
tslib_1.__decorate([
|
|
146
|
+
(0, type_graphql_1.Field)(() => graphql_scalars_1.GraphQLJSON, { nullable: true, description: 'The reads the draft rested on: tool, category, ids, rows, hash, ok or the error code.' }),
|
|
147
|
+
tslib_1.__metadata("design:type", Object),
|
|
148
|
+
tslib_1.__metadata("design:paramtypes", [])
|
|
149
|
+
], AssistantRun.prototype, "readsJson", null);
|
|
150
|
+
tslib_1.__decorate([
|
|
151
|
+
(0, typeorm_1.Column)({ type: 'simple-array', nullable: true }),
|
|
152
|
+
(0, type_graphql_1.Field)(() => [String], { nullable: true, description: 'GraphQL doors the reads went through. A reader of the draft must pass all of them.' }),
|
|
153
|
+
tslib_1.__metadata("design:type", Array)
|
|
154
|
+
], AssistantRun.prototype, "doors", void 0);
|
|
155
|
+
tslib_1.__decorate([
|
|
156
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
157
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Why it failed or was refused - a code; the screen says it.' }),
|
|
158
|
+
tslib_1.__metadata("design:type", String)
|
|
159
|
+
], AssistantRun.prototype, "outcomeCode", void 0);
|
|
160
|
+
tslib_1.__decorate([
|
|
161
|
+
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
|
162
|
+
tslib_1.__metadata("design:type", String)
|
|
163
|
+
], AssistantRun.prototype, "outcomeParams", void 0);
|
|
164
|
+
tslib_1.__decorate([
|
|
165
|
+
(0, type_graphql_1.Field)(() => graphql_scalars_1.GraphQLJSON, { nullable: true, description: 'Values of the outcome code.' }),
|
|
166
|
+
tslib_1.__metadata("design:type", Object),
|
|
167
|
+
tslib_1.__metadata("design:paramtypes", [])
|
|
168
|
+
], AssistantRun.prototype, "outcomeParamsJson", null);
|
|
169
|
+
tslib_1.__decorate([
|
|
170
|
+
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
|
171
|
+
tslib_1.__metadata("design:type", String)
|
|
172
|
+
], AssistantRun.prototype, "attempts", void 0);
|
|
173
|
+
tslib_1.__decorate([
|
|
174
|
+
(0, type_graphql_1.Field)(() => graphql_scalars_1.GraphQLJSON, { nullable: true, description: 'How the earlier attempts ended.' }),
|
|
175
|
+
tslib_1.__metadata("design:type", Object),
|
|
176
|
+
tslib_1.__metadata("design:paramtypes", [])
|
|
177
|
+
], AssistantRun.prototype, "attemptsJson", null);
|
|
178
|
+
tslib_1.__decorate([
|
|
179
|
+
(0, typeorm_1.Column)({ type: 'varchar', length: 1024, nullable: true }),
|
|
180
|
+
tslib_1.__metadata("design:type", String)
|
|
181
|
+
], AssistantRun.prototype, "groundingWarnings", void 0);
|
|
182
|
+
tslib_1.__decorate([
|
|
183
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
184
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'The AI agent that answered.' }),
|
|
185
|
+
tslib_1.__metadata("design:type", String)
|
|
186
|
+
], AssistantRun.prototype, "agentId", void 0);
|
|
187
|
+
tslib_1.__decorate([
|
|
188
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
189
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'provider:model.' }),
|
|
190
|
+
tslib_1.__metadata("design:type", String)
|
|
191
|
+
], AssistantRun.prototype, "clientId", void 0);
|
|
192
|
+
tslib_1.__decorate([
|
|
193
|
+
(0, typeorm_1.Column)({ type: 'int', default: 0 }),
|
|
194
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'Model requests of this attempt.' }),
|
|
195
|
+
tslib_1.__metadata("design:type", Number)
|
|
196
|
+
], AssistantRun.prototype, "modelCalls", void 0);
|
|
197
|
+
tslib_1.__decorate([
|
|
198
|
+
(0, typeorm_1.Column)({ type: 'int', default: 0 }),
|
|
199
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'Input tokens of this attempt.' }),
|
|
200
|
+
tslib_1.__metadata("design:type", Number)
|
|
201
|
+
], AssistantRun.prototype, "inputTokens", void 0);
|
|
202
|
+
tslib_1.__decorate([
|
|
203
|
+
(0, typeorm_1.Column)({ type: 'int', default: 0 }),
|
|
204
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'Output tokens of this attempt.' }),
|
|
205
|
+
tslib_1.__metadata("design:type", Number)
|
|
206
|
+
], AssistantRun.prototype, "outputTokens", void 0);
|
|
207
|
+
tslib_1.__decorate([
|
|
208
|
+
(0, typeorm_1.Column)({ type: 'int', default: 0 }),
|
|
209
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.Int, { description: 'Cards a read offered that were not kept - there was no person to press them.' }),
|
|
210
|
+
tslib_1.__metadata("design:type", Number)
|
|
211
|
+
], AssistantRun.prototype, "cardsDropped", void 0);
|
|
212
|
+
tslib_1.__decorate([
|
|
213
|
+
(0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
|
|
214
|
+
(0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true, description: 'Creator.' }),
|
|
215
|
+
tslib_1.__metadata("design:type", auth_base_1.User)
|
|
216
|
+
], AssistantRun.prototype, "creator", void 0);
|
|
217
|
+
tslib_1.__decorate([
|
|
218
|
+
(0, typeorm_1.RelationId)((run) => run.creator),
|
|
219
|
+
tslib_1.__metadata("design:type", String)
|
|
220
|
+
], AssistantRun.prototype, "creatorId", void 0);
|
|
221
|
+
tslib_1.__decorate([
|
|
222
|
+
(0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
|
|
223
|
+
(0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true, description: 'Last updater.' }),
|
|
224
|
+
tslib_1.__metadata("design:type", auth_base_1.User)
|
|
225
|
+
], AssistantRun.prototype, "updater", void 0);
|
|
226
|
+
tslib_1.__decorate([
|
|
227
|
+
(0, typeorm_1.RelationId)((run) => run.updater),
|
|
228
|
+
tslib_1.__metadata("design:type", String)
|
|
229
|
+
], AssistantRun.prototype, "updaterId", void 0);
|
|
230
|
+
tslib_1.__decorate([
|
|
231
|
+
(0, typeorm_1.CreateDateColumn)(),
|
|
232
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Creation timestamp.' }),
|
|
233
|
+
tslib_1.__metadata("design:type", Date)
|
|
234
|
+
], AssistantRun.prototype, "createdAt", void 0);
|
|
235
|
+
tslib_1.__decorate([
|
|
236
|
+
(0, typeorm_1.UpdateDateColumn)(),
|
|
237
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Last update timestamp.' }),
|
|
238
|
+
tslib_1.__metadata("design:type", Date)
|
|
239
|
+
], AssistantRun.prototype, "updatedAt", void 0);
|
|
240
|
+
exports.AssistantRun = AssistantRun = tslib_1.__decorate([
|
|
241
|
+
(0, typeorm_1.Entity)()
|
|
242
|
+
/* One occurrence, one row - two first calls at once make one row and the other reads it (§5). */
|
|
243
|
+
,
|
|
244
|
+
(0, typeorm_1.Index)('ix_assistant_run_0', (run) => [run.domain, run.source, run.subject, run.scheduledAt], { unique: true }),
|
|
245
|
+
(0, typeorm_1.Index)('ix_assistant_run_1', (run) => [run.domain, run.source, run.subject, run.createdAt]),
|
|
246
|
+
(0, type_graphql_1.ObjectType)({ description: 'One scheduled run of an assistant mode with no person in it, and the draft it left.' })
|
|
247
|
+
], AssistantRun);
|
|
248
|
+
//# sourceMappingURL=assistant-run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assistant-run.js","sourceRoot":"","sources":["../../../server/service/unattended-run/assistant-run.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * AssistantRun — one occurrence of a mode run with no person in it, and what it left (design/ai/unattended-run.md).\n *\n * The one place the facts of an AI run are kept: its attempts, its state, the draft, the reads the draft rested on,\n * what it spent and the doors behind it. The application that scheduled it keeps its own facts and points here by\n * (source, subject, scheduledAt) or by id - it does not copy these (chief architect ruling, 2026-10-20).\n */\nimport { Column, CreateDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\nimport { Field, ID, Int, ObjectType } from 'type-graphql'\nimport { GraphQLJSON } from 'graphql-scalars'\n\nimport { Domain } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { config } from '@things-factory/env'\n\nconst ORMCONFIG = config.get('ormconfig', {})\nconst DATABASE_TYPE = ORMCONFIG.type\n\nconst LONG_TEXT = {\n type:\n DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'\n ? 'longtext'\n : DATABASE_TYPE == 'oracle'\n ? 'clob'\n : DATABASE_TYPE == 'mssql'\n ? 'nvarchar'\n : 'text',\n length: DATABASE_TYPE == 'mssql' ? 'MAX' : undefined,\n nullable: true\n} as const\n\nconst parsed = (text?: string | null) => {\n if (!text) return null\n try {\n return JSON.parse(text)\n } catch {\n return null\n }\n}\n\n@Entity()\n/* One occurrence, one row - two first calls at once make one row and the other reads it (§5). */\n@Index('ix_assistant_run_0', (run: AssistantRun) => [run.domain, run.source, run.subject, run.scheduledAt], { unique: true })\n@Index('ix_assistant_run_1', (run: AssistantRun) => [run.domain, run.source, run.subject, run.createdAt])\n@ObjectType({ description: 'One scheduled run of an assistant mode with no person in it, and the draft it left.' })\nexport class AssistantRun {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID, { description: 'Run id.' })\n readonly id?: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'The domain the run is in.' })\n domain?: Domain\n\n @RelationId((run: AssistantRun) => run.domain)\n domainId?: string\n\n @Column()\n @Field({ description: 'Readable name of the occurrence - source, subject and time.' })\n name: string\n\n @Column({ type: 'text', nullable: true })\n @Field({ nullable: true, description: 'Description.' })\n description?: string\n\n @Column({ length: 64 })\n @Field({ description: \"Who scheduled it - '<app>.<work>', e.g. 'office.strategy-review'.\" })\n source: string\n\n @Column({ length: 64 })\n @Field({ description: \"What it is about in the source's terms, e.g. a policy id.\" })\n subject: string\n\n @Column()\n @Field({ description: 'The occurrence this run is.' })\n scheduledAt: Date\n\n @Column({ length: 64 })\n @Field({ description: 'The assistant mode that ran.' })\n modeKind: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'What the mode was about.' })\n modeTarget?: string\n\n @ManyToOne(type => User)\n @Field(type => User, { nullable: true, description: 'The person the run acted as - its privileges and doors were theirs.' })\n runAs?: User\n\n @RelationId((run: AssistantRun) => run.runAs)\n runAsId?: string\n\n @Column({ length: 16 })\n @Field({ description: \"'running' | 'succeeded' | 'failed' | 'refused'.\" })\n status: string\n\n @Column({ type: 'int', default: 1 })\n @Field(type => Int, { description: 'Which attempt at this occurrence the row holds, from 1.' })\n attempt: number\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'When this attempt started.' })\n startedAt?: Date\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Past this a running attempt is taken as gone and the next call takes the occurrence over.' })\n deadlineAt?: Date\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'When this attempt ended.' })\n finishedAt?: Date\n\n @Column(LONG_TEXT as any)\n @Field({ nullable: true, description: 'The draft - only when the run succeeded.' })\n draft?: string\n\n /** Each call of the run as the audit digests it (`ToolCallRecord`, never raw values), as JSON. */\n @Column(LONG_TEXT as any)\n reads?: string\n\n @Field(() => GraphQLJSON, { nullable: true, description: 'The reads the draft rested on: tool, category, ids, rows, hash, ok or the error code.' })\n get readsJson(): any {\n return parsed(this.reads)\n }\n\n @Column({ type: 'simple-array', nullable: true })\n @Field(() => [String], { nullable: true, description: 'GraphQL doors the reads went through. A reader of the draft must pass all of them.' })\n doors?: string[]\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Why it failed or was refused - a code; the screen says it.' })\n outcomeCode?: string\n\n @Column({ type: 'text', nullable: true })\n outcomeParams?: string\n\n @Field(() => GraphQLJSON, { nullable: true, description: 'Values of the outcome code.' })\n get outcomeParamsJson(): any {\n return parsed(this.outcomeParams)\n }\n\n /** The earlier attempts' endings, `[{ attempt, status, outcomeCode, startedAt, finishedAt }]`, as JSON. */\n @Column({ type: 'text', nullable: true })\n attempts?: string\n\n @Field(() => GraphQLJSON, { nullable: true, description: 'How the earlier attempts ended.' })\n get attemptsJson(): any {\n return parsed(this.attempts)\n }\n\n @Column({ type: 'varchar', length: 1024, nullable: true })\n groundingWarnings?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'The AI agent that answered.' })\n agentId?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'provider:model.' })\n clientId?: string\n\n @Column({ type: 'int', default: 0 })\n @Field(type => Int, { description: 'Model requests of this attempt.' })\n modelCalls: number\n\n @Column({ type: 'int', default: 0 })\n @Field(type => Int, { description: 'Input tokens of this attempt.' })\n inputTokens: number\n\n @Column({ type: 'int', default: 0 })\n @Field(type => Int, { description: 'Output tokens of this attempt.' })\n outputTokens: number\n\n @Column({ type: 'int', default: 0 })\n @Field(type => Int, { description: 'Cards a read offered that were not kept - there was no person to press them.' })\n cardsDropped: number\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Creator.' })\n creator?: User\n\n @RelationId((run: AssistantRun) => run.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true, description: 'Last updater.' })\n updater?: User\n\n @RelationId((run: AssistantRun) => run.updater)\n updaterId?: string\n\n @CreateDateColumn()\n @Field({ nullable: true, description: 'Creation timestamp.' })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true, description: 'Last update timestamp.' })\n updatedAt?: Date\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AssistantRun } from './assistant-run.js';
|
|
2
|
+
export { AssistantRun };
|
|
3
|
+
export { runAssistantUnattended, findAssistantRun } from './run-unattended.js';
|
|
4
|
+
export type { UnattendedRunInput, UnattendedRunDeps } from './run-unattended.js';
|
|
5
|
+
export { UNATTENDED_DEFAULTS } from './limits.js';
|
|
6
|
+
export { assistantRunOutcomeText, ASSISTANT_RUN_OUTCOME_ENGLISH } from './run-outcome.js';
|
|
7
|
+
export type { AssistantRunStatus } from './run-ledger.js';
|
|
8
|
+
export declare const entities: (typeof AssistantRun)[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.entities = exports.ASSISTANT_RUN_OUTCOME_ENGLISH = exports.assistantRunOutcomeText = exports.UNATTENDED_DEFAULTS = exports.findAssistantRun = exports.runAssistantUnattended = exports.AssistantRun = void 0;
|
|
4
|
+
const assistant_run_js_1 = require("./assistant-run.js");
|
|
5
|
+
Object.defineProperty(exports, "AssistantRun", { enumerable: true, get: function () { return assistant_run_js_1.AssistantRun; } });
|
|
6
|
+
var run_unattended_js_1 = require("./run-unattended.js");
|
|
7
|
+
Object.defineProperty(exports, "runAssistantUnattended", { enumerable: true, get: function () { return run_unattended_js_1.runAssistantUnattended; } });
|
|
8
|
+
Object.defineProperty(exports, "findAssistantRun", { enumerable: true, get: function () { return run_unattended_js_1.findAssistantRun; } });
|
|
9
|
+
var limits_js_1 = require("./limits.js");
|
|
10
|
+
Object.defineProperty(exports, "UNATTENDED_DEFAULTS", { enumerable: true, get: function () { return limits_js_1.UNATTENDED_DEFAULTS; } });
|
|
11
|
+
var run_outcome_js_1 = require("./run-outcome.js");
|
|
12
|
+
Object.defineProperty(exports, "assistantRunOutcomeText", { enumerable: true, get: function () { return run_outcome_js_1.assistantRunOutcomeText; } });
|
|
13
|
+
Object.defineProperty(exports, "ASSISTANT_RUN_OUTCOME_ENGLISH", { enumerable: true, get: function () { return run_outcome_js_1.ASSISTANT_RUN_OUTCOME_ENGLISH; } });
|
|
14
|
+
exports.entities = [assistant_run_js_1.AssistantRun];
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/unattended-run/index.ts"],"names":[],"mappings":";;;AAAA,yDAAiD;AAExC,6FAFA,+BAAY,OAEA;AACrB,yDAA8E;AAArE,2HAAA,sBAAsB,OAAA;AAAE,qHAAA,gBAAgB,OAAA;AAEjD,yCAAiD;AAAxC,gHAAA,mBAAmB,OAAA;AAC5B,mDAAyF;AAAhF,yHAAA,uBAAuB,OAAA;AAAE,+HAAA,6BAA6B,OAAA;AAGlD,QAAA,QAAQ,GAAG,CAAC,+BAAY,CAAC,CAAA","sourcesContent":["import { AssistantRun } from './assistant-run.js'\n\nexport { AssistantRun }\nexport { runAssistantUnattended, findAssistantRun } from './run-unattended.js'\nexport type { UnattendedRunInput, UnattendedRunDeps } from './run-unattended.js'\nexport { UNATTENDED_DEFAULTS } from './limits.js'\nexport { assistantRunOutcomeText, ASSISTANT_RUN_OUTCOME_ENGLISH } from './run-outcome.js'\nexport type { AssistantRunStatus } from './run-ledger.js'\n\nexport const entities = [AssistantRun]\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { UnattendedLimits } from '../assistant-mode/types.js';
|
|
2
|
+
export declare const UNATTENDED_DEFAULTS: Required<UnattendedLimits>;
|
|
3
|
+
/**
|
|
4
|
+
* How long past its time limit a running attempt is still taken as alive. A server that died mid-run leaves the row
|
|
5
|
+
* `running`; past this the next call takes the occurrence over (§5).
|
|
6
|
+
*/
|
|
7
|
+
export declare const ABANDON_MARGIN_MS = 30000;
|
|
8
|
+
/** The mode's limits, each absent or unusable one at its default. */
|
|
9
|
+
export declare function unattendedLimits(declared: UnattendedLimits | undefined): Required<UnattendedLimits>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ABANDON_MARGIN_MS = exports.UNATTENDED_DEFAULTS = void 0;
|
|
4
|
+
exports.unattendedLimits = unattendedLimits;
|
|
5
|
+
exports.UNATTENDED_DEFAULTS = {
|
|
6
|
+
maxModelCalls: 8,
|
|
7
|
+
maxTokens: 60000,
|
|
8
|
+
timeoutMs: 120000
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* How long past its time limit a running attempt is still taken as alive. A server that died mid-run leaves the row
|
|
12
|
+
* `running`; past this the next call takes the occurrence over (§5).
|
|
13
|
+
*/
|
|
14
|
+
exports.ABANDON_MARGIN_MS = 30000;
|
|
15
|
+
/** The mode's limits, each absent or unusable one at its default. */
|
|
16
|
+
function unattendedLimits(declared) {
|
|
17
|
+
const pick = (value, fallback) => (typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : fallback);
|
|
18
|
+
return {
|
|
19
|
+
maxModelCalls: Math.floor(pick(declared?.maxModelCalls, exports.UNATTENDED_DEFAULTS.maxModelCalls)),
|
|
20
|
+
maxTokens: pick(declared?.maxTokens, exports.UNATTENDED_DEFAULTS.maxTokens),
|
|
21
|
+
timeoutMs: pick(declared?.timeoutMs, exports.UNATTENDED_DEFAULTS.timeoutMs)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=limits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limits.js","sourceRoot":"","sources":["../../../server/service/unattended-run/limits.ts"],"names":[],"mappings":";;;AAgBA,4CAOC;AApBY,QAAA,mBAAmB,GAA+B;IAC7D,aAAa,EAAE,CAAC;IAChB,SAAS,EAAE,KAAK;IAChB,SAAS,EAAE,MAAM;CAClB,CAAA;AAED;;;GAGG;AACU,QAAA,iBAAiB,GAAG,KAAK,CAAA;AAEtC,qEAAqE;AACrE,SAAgB,gBAAgB,CAAC,QAAsC;IACrE,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,QAAgB,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;IACxI,OAAO;QACL,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,2BAAmB,CAAC,aAAa,CAAC,CAAC;QAC3F,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,2BAAmB,CAAC,SAAS,CAAC;QACnE,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,2BAAmB,CAAC,SAAS,CAAC;KACpE,CAAA;AACH,CAAC","sourcesContent":["/* Pure. What one unattended run of a mode may spend (design/ai/unattended-run.md §4). */\nimport type { UnattendedLimits } from '../assistant-mode/types.js'\n\nexport const UNATTENDED_DEFAULTS: Required<UnattendedLimits> = {\n maxModelCalls: 8,\n maxTokens: 60000,\n timeoutMs: 120000\n}\n\n/**\n * How long past its time limit a running attempt is still taken as alive. A server that died mid-run leaves the row\n * `running`; past this the next call takes the occurrence over (§5).\n */\nexport const ABANDON_MARGIN_MS = 30000\n\n/** The mode's limits, each absent or unusable one at its default. */\nexport function unattendedLimits(declared: UnattendedLimits | undefined): Required<UnattendedLimits> {\n const pick = (value: unknown, fallback: number) => (typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : fallback)\n return {\n maxModelCalls: Math.floor(pick(declared?.maxModelCalls, UNATTENDED_DEFAULTS.maxModelCalls)),\n maxTokens: pick(declared?.maxTokens, UNATTENDED_DEFAULTS.maxTokens),\n timeoutMs: pick(declared?.timeoutMs, UNATTENDED_DEFAULTS.timeoutMs)\n }\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** The same door a person passes to ask the assistant (`assistantChat`). */
|
|
2
|
+
export declare const ASK_ASSISTANT_GATE: {
|
|
3
|
+
category: string;
|
|
4
|
+
privilege: string;
|
|
5
|
+
owner: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type RunAsRefusal = 'assistant-run-as-unknown' | 'assistant-run-as-inactive' | 'assistant-run-as-not-member' | 'assistant-run-as-not-permitted';
|
|
8
|
+
export interface RunAsChecks<TUser, TDomain> {
|
|
9
|
+
/** The user as stored now - not as the caller last saw them. */
|
|
10
|
+
findUser: (id: string) => Promise<TUser | undefined | null>;
|
|
11
|
+
/** Whether they can enter this domain - auth-base `canUserCheckinDomain`. */
|
|
12
|
+
mayCheckin: (user: TUser, domain: TDomain) => Promise<boolean>;
|
|
13
|
+
/** auth-base `checkPermission`, with no address and no prohibitions: there is no request. */
|
|
14
|
+
permits: (gate: typeof ASK_ASSISTANT_GATE, user: TUser, domain: TDomain) => Promise<boolean>;
|
|
15
|
+
}
|
|
16
|
+
/** `user` is the account as `findUser` read it just now - absent when there is none. */
|
|
17
|
+
export declare function judgeRunAs<TUser extends {
|
|
18
|
+
id?: string;
|
|
19
|
+
status?: string;
|
|
20
|
+
}, TDomain>(user: TUser | undefined | null, domain: TDomain, checks: Omit<RunAsChecks<TUser, TDomain>, 'findUser'>): Promise<{
|
|
21
|
+
user: TUser;
|
|
22
|
+
} | {
|
|
23
|
+
refused: RunAsRefusal;
|
|
24
|
+
}>;
|