@xfey/tutti 0.1.126 → 0.1.128

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +2 -0
  2. package/dist/approvals/decision-command.d.ts +2 -2
  3. package/dist/chat-assistant/diagnostics.d.ts +11 -3
  4. package/dist/chat-assistant/diagnostics.js +5 -2
  5. package/dist/chat-assistant/failures.d.ts +27 -0
  6. package/dist/chat-assistant/failures.js +102 -0
  7. package/dist/chat-assistant/index.d.ts +14 -2
  8. package/dist/chat-assistant/index.js +241 -54
  9. package/dist/chat-assistant/language-context.d.ts +8 -0
  10. package/dist/chat-assistant/language-context.js +41 -0
  11. package/dist/chat-assistant/requests.d.ts +30 -0
  12. package/dist/chat-assistant/requests.js +58 -0
  13. package/dist/collaboration-ingestion/clarification.js +3 -1
  14. package/dist/collaboration-ingestion/main-chat.js +1 -0
  15. package/dist/collaboration-ingestion/types.d.ts +2 -0
  16. package/dist/collaboration-state/clarification-snapshot.d.ts +5 -5
  17. package/dist/collaboration-state/communication-language.d.ts +31 -0
  18. package/dist/collaboration-state/communication-language.js +36 -0
  19. package/dist/collaboration-state/task-compile-context.d.ts +1 -1
  20. package/dist/collaboration-state/task-compile-context.js +20 -1
  21. package/dist/collaboration-state/task-compile-requests.d.ts +6 -0
  22. package/dist/collaboration-state/task-compile-requests.js +16 -0
  23. package/dist/communication-language/index.d.ts +75 -0
  24. package/dist/communication-language/index.js +122 -0
  25. package/dist/communication-language/live-smoke-cli.d.ts +2 -0
  26. package/dist/communication-language/live-smoke-cli.js +368 -0
  27. package/dist/communication-language/prompt.d.ts +22 -0
  28. package/dist/communication-language/prompt.js +73 -0
  29. package/dist/control-plane/communication-language.d.ts +33 -0
  30. package/dist/control-plane/communication-language.js +72 -0
  31. package/dist/control-plane/context-sync.js +7 -0
  32. package/dist/control-plane/follow-up-output.js +25 -4
  33. package/dist/control-plane/follow-up-start.js +17 -0
  34. package/dist/control-plane/project-brief-refresh.js +10 -1
  35. package/dist/control-plane/project-context-bootstrap.d.ts +2 -0
  36. package/dist/control-plane/project-context-bootstrap.js +8 -0
  37. package/dist/control-plane/reference-summary-refresh.js +7 -0
  38. package/dist/control-plane/run-start.js +14 -6
  39. package/dist/control-plane/scratchpad-refresh-start.d.ts +1 -0
  40. package/dist/control-plane/scratchpad-refresh-start.js +13 -0
  41. package/dist/control-plane/scratchpad-refresh.d.ts +2 -0
  42. package/dist/control-plane/scratchpad-refresh.js +40 -26
  43. package/dist/control-plane/task-compile-continuation.js +16 -1
  44. package/dist/control-plane/task-compile-output.js +38 -14
  45. package/dist/control-plane/task-compile-request-status.d.ts +6 -0
  46. package/dist/control-plane/task-compile-request-status.js +70 -0
  47. package/dist/control-plane/task-compile-start.d.ts +1 -0
  48. package/dist/control-plane/task-compile-start.js +62 -3
  49. package/dist/control-plane/types.d.ts +2 -0
  50. package/dist/control-plane/workflows/openai.js +48 -28
  51. package/dist/control-plane/workflows/types.d.ts +18 -13
  52. package/dist/prompt-templates/index.d.ts +1 -1
  53. package/dist/prompt-templates/index.js +2 -0
  54. package/dist/providers/failure-classification.d.ts +23 -0
  55. package/dist/providers/failure-classification.js +43 -0
  56. package/dist/reference-access/read-evidence.d.ts +2 -0
  57. package/dist/reference-access/read-evidence.js +5 -0
  58. package/dist/reference-access/service.d.ts +2 -0
  59. package/dist/reference-access/service.js +2 -0
  60. package/dist/run-pipeline/task-run-invocation.js +12 -9
  61. package/dist/runtime-failures.js +15 -1
  62. package/dist/server-shell/cli/external-reference-runtime.js +6 -3
  63. package/dist/server-shell/cli/host-server-runtime.js +4 -1
  64. package/dist/server-shell/cli/relay-registration.js +1 -0
  65. package/dist/server-shell/http/routes/project-api/messages-routes.js +22 -1
  66. package/dist/server-shell/http/routes/project-api/openapi-collaboration-routes.d.ts +140 -5
  67. package/dist/server-shell/http/routes/project-api/openapi-collaboration-routes.js +29 -2
  68. package/dist/server-shell/http/routes/project-api/openapi-skills-routes.d.ts +2 -0
  69. package/dist/server-shell/http/routes/project-api/openapi-workspace-routes.d.ts +6 -0
  70. package/dist/server-shell/http/routes/project-api/openapi.d.ts +148 -5
  71. package/dist/server-shell/http/routes/project-api/schemas.d.ts +6 -0
  72. package/dist/server-shell/http/routes/project-api/schemas.js +1 -0
  73. package/dist/server-shell/http/routes/project-api/types.d.ts +1 -0
  74. package/dist/server-shell/http/routes/project-api/workflow-routes.js +39 -3
  75. package/dist/server-shell/http/routes/project-api/workspace-projections.js +1 -0
  76. package/dist/server-shell/http/validation.js +8 -2
  77. package/dist/server-shell/local-console/managed-project-service.d.ts +1 -1
  78. package/dist/server-shell/managed-access/transport.d.ts +1 -1
  79. package/migrations/0023_communication_language.sql +14 -0
  80. package/migrations/0024_chat_requests.sql +19 -0
  81. package/migrations/0025_task_compile_requests.sql +50 -0
  82. package/migrations/README.md +3 -1
  83. package/node_modules/@tutti/relay-client/dist/host-control.d.ts +1 -0
  84. package/node_modules/@tutti/relay-client/dist/host-control.js +1 -0
  85. package/node_modules/@tutti/shared/dist/schemas/api/index.d.ts +1 -0
  86. package/node_modules/@tutti/shared/dist/schemas/api/index.js +1 -0
  87. package/node_modules/@tutti/shared/dist/schemas/api/operation-status.d.ts +174 -0
  88. package/node_modules/@tutti/shared/dist/schemas/api/operation-status.js +75 -0
  89. package/node_modules/@tutti/shared/dist/schemas/api/primitives.d.ts +1 -0
  90. package/node_modules/@tutti/shared/dist/schemas/api/primitives.js +1 -0
  91. package/node_modules/@tutti/shared/dist/schemas/api/workspace-commands.d.ts +1 -0
  92. package/node_modules/@tutti/shared/dist/schemas/api/workspace-commands.js +2 -1
  93. package/package.json +1 -1
  94. package/prompts/README.md +1 -0
  95. package/prompts/chat-assistant.md +1 -1
  96. package/prompts/communication-language-result.md +27 -0
  97. package/prompts/communication-language.md +50 -0
  98. package/prompts/procedures/follow-up-check.md +1 -1
  99. package/prompts/procedures/scratchpad-refresh.md +2 -2
  100. package/prompts/procedures/task-compile.md +1 -1
  101. package/prompts/prompt-flow-map.md +2 -0
  102. package/web/assets/{homepage-motion-scene-DyEmWwvt.js → homepage-motion-scene-BcMt0AVW.js} +1 -1
  103. package/web/assets/index-2eX37Jx6.js +70 -0
  104. package/web/assets/index-BJvKuUiT.css +1 -0
  105. package/web/index.html +2 -2
  106. package/web/assets/index-By3idT4U.js +0 -70
  107. package/web/assets/index-DSBjOZmJ.css +0 -1
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # server
2
2
 
3
+ 当前源码的[协作输出语言](../../docs/system/communication-language.md)由 Host 统一处理:migration `0023`、共享 prompt、Scratchpad/workflow/task 语言继承。通过 Host npm 包交付,需更新项目 Host 才会生效,不依赖 Web 或飞书端新增设置;对照模型的引用语言误判作为已知项保留,不宣称所有模型均稳定通过。
4
+
3
5
  ## 作用
4
6
 
5
7
  `apps/server` 是 Tutti 的项目 host service,也是机器级 Local Console 的进程入口。
@@ -25,8 +25,8 @@ export declare function executeApprovalDecisionCommand(input: {
25
25
  state: "pending";
26
26
  request: {
27
27
  expires_at?: string;
28
- task_id?: string;
29
28
  activity_ref?: string;
29
+ task_id?: string;
30
30
  reason?: string;
31
31
  file_change?: {
32
32
  paths?: string[];
@@ -69,8 +69,8 @@ export declare function executeApprovalDecisionCommand(input: {
69
69
  state: "resolved";
70
70
  request: {
71
71
  expires_at?: string;
72
- task_id?: string;
73
72
  activity_ref?: string;
73
+ task_id?: string;
74
74
  reason?: string;
75
75
  file_change?: {
76
76
  paths?: string[];
@@ -1,11 +1,17 @@
1
1
  import type { ProviderInvocationProgress } from "../providers/invocation-progress.js";
2
+ import type { languageDiagnosticFields } from "../communication-language/index.js";
3
+ import type { ChatFailureCode } from "./failures.js";
2
4
  export type ChatAssistantLogger = {
3
5
  info: (fields: Record<string, unknown>, message: string) => void;
4
6
  warn: (fields: Record<string, unknown>, message: string) => void;
5
7
  };
6
- type ChatAssistantProgress = ProviderInvocationProgress | {
7
- stage: "queued" | "inspection_wait" | "model_requested" | "reply_persisted" | "failed" | "skipped";
8
- reason_code?: "queue_full" | "stopping" | "context_unavailable" | "answer_failed" | "reply_failed";
8
+ type ChatAssistantProgress = ProviderInvocationProgress | ({
9
+ stage: "language_context";
10
+ } & ReturnType<typeof languageDiagnosticFields>) | {
11
+ stage: "queued" | "inspection_wait" | "model_requested" | "reply_persisted" | "notification_failed" | "failed" | "skipped";
12
+ reason_code?: "queue_full" | "stopping" | "context_unavailable" | "answer_failed" | "reply_failed" | "request_changed";
13
+ error_code?: ChatFailureCode;
14
+ diagnostic_id?: string;
9
15
  reference_source_count?: number;
10
16
  };
11
17
  export declare function createChatAssistantDiagnostics(options: {
@@ -13,6 +19,8 @@ export declare function createChatAssistantDiagnostics(options: {
13
19
  projectId: string;
14
20
  triggerMessageId: string;
15
21
  scope: string;
22
+ requestRef?: string;
23
+ attemptRef?: string;
16
24
  }): (event: ChatAssistantProgress) => void;
17
25
  export {};
18
26
  //# sourceMappingURL=diagnostics.d.ts.map
@@ -1,18 +1,21 @@
1
1
  import { createEventRef } from "@tutti/shared/ids";
2
2
  export function createChatAssistantDiagnostics(options) {
3
- const requestRef = createEventRef();
3
+ const requestRef = options.requestRef ?? createEventRef();
4
4
  const started = performance.now();
5
5
  return (event) => {
6
6
  try {
7
7
  const fields = {
8
8
  project_id: options.projectId,
9
9
  chat_request_ref: requestRef,
10
+ ...(options.attemptRef === undefined ? {} : { attempt_ref: options.attemptRef }),
10
11
  trigger_message_ref: options.triggerMessageId,
11
12
  scope: options.scope,
12
13
  elapsed_ms: Math.round(performance.now() - started),
13
14
  ...event,
14
15
  };
15
- if (event.stage === "failed" || event.stage === "provider_failed") {
16
+ if (event.stage === "failed" ||
17
+ event.stage === "provider_failed" ||
18
+ event.stage === "notification_failed") {
16
19
  options.logger?.warn(fields, "Chat assistant progress");
17
20
  }
18
21
  else {
@@ -0,0 +1,27 @@
1
+ import type { OperationFailure } from "@tutti/shared/schemas/api";
2
+ declare const failures: {
3
+ readonly reference_authorization_required: readonly ["access", "none", "Authorize document access using the group card, then send your question again. Authorization does not restart this answer."];
4
+ readonly chat_queue_full: readonly ["capacity", "resend_request", "Tutti is busy answering other questions. Try again shortly."];
5
+ readonly chat_context_unavailable: readonly ["interrupted", "none", "This question's conversation is no longer available."];
6
+ readonly host_restarted: readonly ["interrupted", "resend_request", "The Host restarted before this answer was saved. Send your question again."];
7
+ readonly provider_not_configured: readonly ["configuration", "check_provider", "Ask the project owner to configure model access, then send your question again."];
8
+ readonly provider_auth_invalid: readonly ["access", "check_provider", "Model access could not be verified. Ask the project owner to check it."];
9
+ readonly provider_quota_or_billing_required: readonly ["access", "check_provider", "Model credit is unavailable. Ask the project owner to check the account."];
10
+ readonly provider_rate_limited: readonly ["capacity", "resend_request", "The model service is busy. Wait a moment, then send your question again."];
11
+ readonly provider_network_error: readonly ["dependency", "resend_request", "The model service could not be reached. Try again when the connection is available."];
12
+ readonly provider_model_unavailable: readonly ["configuration", "check_provider", "The selected model is unavailable. Ask the project owner to check model access."];
13
+ readonly provider_timeout: readonly ["dependency", "resend_request", "The model did not finish answering in time. You can send your question again."];
14
+ readonly provider_output_invalid: readonly ["dependency", "resend_request", "The model did not return a usable answer. You can send your question again."];
15
+ readonly provider_lifecycle_failed: readonly ["internal", "restart_host", "The model process could not close safely. Restart the Host before trying again."];
16
+ readonly chat_reply_persistence_failed: readonly ["internal", "contact_support", "The answer could not be saved. Check the Host diagnostics before trying again."];
17
+ readonly internal_error: readonly ["internal", "contact_support", "Tutti could not complete this read-only answer. Share the diagnostic ID if this persists."];
18
+ };
19
+ export type ChatFailureCode = keyof typeof failures;
20
+ type ChatFailure = OperationFailure & {
21
+ code: ChatFailureCode;
22
+ };
23
+ export declare function chatFailure(code: ChatFailureCode, diagnosticId?: string): ChatFailure;
24
+ export declare function chatFailureMessage(failure: OperationFailure): string;
25
+ export declare function classifyChatFailure(error: unknown, diagnosticId: string): ChatFailure;
26
+ export {};
27
+ //# sourceMappingURL=failures.d.ts.map
@@ -0,0 +1,102 @@
1
+ import { createEventRef } from "@tutti/shared/ids";
2
+ import { providerFailureCode } from "../providers/failure-classification.js";
3
+ const failures = {
4
+ reference_authorization_required: [
5
+ "access",
6
+ "none",
7
+ "Authorize document access using the group card, then send your question again. Authorization does not restart this answer.",
8
+ ],
9
+ chat_queue_full: [
10
+ "capacity",
11
+ "resend_request",
12
+ "Tutti is busy answering other questions. Try again shortly.",
13
+ ],
14
+ chat_context_unavailable: [
15
+ "interrupted",
16
+ "none",
17
+ "This question's conversation is no longer available.",
18
+ ],
19
+ host_restarted: [
20
+ "interrupted",
21
+ "resend_request",
22
+ "The Host restarted before this answer was saved. Send your question again.",
23
+ ],
24
+ provider_not_configured: [
25
+ "configuration",
26
+ "check_provider",
27
+ "Ask the project owner to configure model access, then send your question again.",
28
+ ],
29
+ provider_auth_invalid: [
30
+ "access",
31
+ "check_provider",
32
+ "Model access could not be verified. Ask the project owner to check it.",
33
+ ],
34
+ provider_quota_or_billing_required: [
35
+ "access",
36
+ "check_provider",
37
+ "Model credit is unavailable. Ask the project owner to check the account.",
38
+ ],
39
+ provider_rate_limited: [
40
+ "capacity",
41
+ "resend_request",
42
+ "The model service is busy. Wait a moment, then send your question again.",
43
+ ],
44
+ provider_network_error: [
45
+ "dependency",
46
+ "resend_request",
47
+ "The model service could not be reached. Try again when the connection is available.",
48
+ ],
49
+ provider_model_unavailable: [
50
+ "configuration",
51
+ "check_provider",
52
+ "The selected model is unavailable. Ask the project owner to check model access.",
53
+ ],
54
+ provider_timeout: [
55
+ "dependency",
56
+ "resend_request",
57
+ "The model did not finish answering in time. You can send your question again.",
58
+ ],
59
+ provider_output_invalid: [
60
+ "dependency",
61
+ "resend_request",
62
+ "The model did not return a usable answer. You can send your question again.",
63
+ ],
64
+ provider_lifecycle_failed: [
65
+ "internal",
66
+ "restart_host",
67
+ "The model process could not close safely. Restart the Host before trying again.",
68
+ ],
69
+ chat_reply_persistence_failed: [
70
+ "internal",
71
+ "contact_support",
72
+ "The answer could not be saved. Check the Host diagnostics before trying again.",
73
+ ],
74
+ internal_error: [
75
+ "internal",
76
+ "contact_support",
77
+ "Tutti could not complete this read-only answer. Share the diagnostic ID if this persists.",
78
+ ],
79
+ };
80
+ export function chatFailure(code, diagnosticId = createEventRef()) {
81
+ const [category, recovery] = failures[code];
82
+ return { code, category, recovery, diagnostic_id: diagnosticId };
83
+ }
84
+ export function chatFailureMessage(failure) {
85
+ const entry = Object.hasOwn(failures, failure.code)
86
+ ? failures[failure.code]
87
+ : failures.internal_error;
88
+ return `${entry[2]} Diagnostic ID: ${failure.diagnostic_id}`;
89
+ }
90
+ // Allowlisted error facts only; neither error.message nor diagnostic callbacks
91
+ // establish business truth. Unknown failures remain non-automatically-retryable.
92
+ export function classifyChatFailure(error, diagnosticId) {
93
+ const value = typeof error === "object" && error !== null
94
+ ? error
95
+ : {};
96
+ const code = typeof value.code === "string" ? value.code : value.reason;
97
+ const mapped = typeof code === "string" && Object.hasOwn(failures, code)
98
+ ? code
99
+ : (providerFailureCode(error) ?? "internal_error");
100
+ return chatFailure(mapped, diagnosticId);
101
+ }
102
+ //# sourceMappingURL=failures.js.map
@@ -1,4 +1,4 @@
1
- import type { ProjectId } from "@tutti/shared/ids";
1
+ import { type ProjectId } from "@tutti/shared/ids";
2
2
  import type { MessageProjection } from "@tutti/shared/schemas/api";
3
3
  import { type ChatAssistantLogger } from "./diagnostics.js";
4
4
  import type { ProviderInvocationProgressObserver } from "../providers/invocation-progress.js";
@@ -33,6 +33,7 @@ export type ReadOnlyChatAssistantEnqueueResult = {
33
33
  triggered: boolean;
34
34
  };
35
35
  export type ReadOnlyChatAssistantHandle = {
36
+ register: (tx: SqliteDatabase, message: MessageProjection) => void;
36
37
  enqueue: (input: ReadOnlyChatAssistantTriggerInput) => ReadOnlyChatAssistantEnqueueResult;
37
38
  waitForIdle: () => Promise<void>;
38
39
  stopAccepting: () => void;
@@ -62,16 +63,26 @@ export declare function isChatAssistantOutput(value: unknown): value is ChatAssi
62
63
  export declare function containsTuttiMention(value: string): boolean;
63
64
  export declare class ReadOnlyChatAssistant implements ReadOnlyChatAssistantHandle {
64
65
  private readonly options;
65
- private readonly pending;
66
66
  private readonly idleWaiters;
67
67
  private active;
68
68
  private accepting;
69
69
  private readonly maxQueuedMentions;
70
+ private recoveryTimer;
71
+ private started;
72
+ private activeAttemptRef;
73
+ private storageFailureReported;
70
74
  constructor(options: ReadOnlyChatAssistantOptions);
75
+ /** Call once after Host recovery/transport wiring. No old messages are backfilled. */
76
+ start(): void;
77
+ register(tx: SqliteDatabase, message: MessageProjection): void;
78
+ private now;
79
+ private report;
71
80
  enqueue(input: ReadOnlyChatAssistantTriggerInput): ReadOnlyChatAssistantEnqueueResult;
72
81
  waitForIdle(): Promise<void>;
73
82
  stopAccepting(): void;
74
83
  private pump;
84
+ private reportStorageFailure;
85
+ private pumpNext;
75
86
  private resolveIdleIfNeeded;
76
87
  private buildMainChatContext;
77
88
  private buildClarificationRoundContext;
@@ -80,6 +91,7 @@ export declare class ReadOnlyChatAssistant implements ReadOnlyChatAssistantHandl
80
91
  private appendMainChatAssistantMessage;
81
92
  private appendClarificationRoundAssistantMessage;
82
93
  private appendAssistantMessageForTrigger;
94
+ private recordReply;
83
95
  private respond;
84
96
  }
85
97
  //# sourceMappingURL=index.d.ts.map