negotium 0.22.2 → 0.22.4

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 (38) hide show
  1. package/bin/negotium.mjs +0 -0
  2. package/dist/agent-helpers.js +601 -42
  3. package/dist/agent-helpers.js.map +8 -6
  4. package/dist/{chunk-gzph93xn.js → chunk-0jtan6fd.js} +3 -3
  5. package/dist/{chunk-gzph93xn.js.map → chunk-0jtan6fd.js.map} +2 -2
  6. package/dist/{chunk-kn8y5scr.js → chunk-rwj7x5pg.js} +4 -1
  7. package/dist/{chunk-kn8y5scr.js.map → chunk-rwj7x5pg.js.map} +3 -3
  8. package/dist/{chunk-bn1tt2qw.js → chunk-y4tyc603.js} +1 -1
  9. package/dist/hosted-agent.js +5 -2
  10. package/dist/hosted-agent.js.map +4 -4
  11. package/dist/main.js +1145 -376
  12. package/dist/main.js.map +22 -20
  13. package/dist/mcp-factories.js +620 -61
  14. package/dist/mcp-factories.js.map +8 -6
  15. package/dist/registry.js +3 -3
  16. package/dist/rollout.js +2 -2
  17. package/dist/runtime/src/agents/mcp-tools/request-vault.ts +616 -0
  18. package/dist/runtime/src/application/topic-service.ts +7 -0
  19. package/dist/runtime/src/index.ts +9 -0
  20. package/dist/runtime/src/mcp-runtime-host.ts +1 -0
  21. package/dist/runtime/src/node-host.ts +5 -0
  22. package/dist/runtime/src/runtime/inbox.ts +33 -171
  23. package/dist/runtime/src/runtime/turn-event-stream.ts +2 -0
  24. package/dist/runtime/src/storage/api-messages.ts +8 -2
  25. package/dist/runtime/src/storage/vault-request-gates.ts +359 -0
  26. package/dist/runtime/src/types/api.ts +23 -1
  27. package/dist/runtime/src/version.ts +1 -1
  28. package/dist/runtime-helpers.js +4 -1
  29. package/dist/runtime-helpers.js.map +3 -3
  30. package/dist/storage.js +8 -4
  31. package/dist/storage.js.map +3 -3
  32. package/dist/types/packages/core/src/agents/mcp-tools/request-vault.d.ts +120 -0
  33. package/dist/types/packages/core/src/storage/api-messages.d.ts +1 -0
  34. package/dist/types/packages/core/src/storage/vault-request-gates.d.ts +69 -0
  35. package/dist/types/packages/core/src/types/api.d.ts +15 -1
  36. package/dist/types/packages/core/src/version.d.ts +1 -1
  37. package/package.json +1 -1
  38. /package/dist/{chunk-bn1tt2qw.js.map → chunk-y4tyc603.js.map} +0 -0
@@ -0,0 +1,120 @@
1
+ import { type SharedMcpTool } from "./common";
2
+ import { type RuntimeProcessLease, type RuntimeProcessLeaseHandle } from "../../storage/runtime-process-leases";
3
+ import { type ClaimVaultRequestGateResult, type PrepareVaultRequestGateResult, type VaultRequestGateCardUpdate } from "../../storage/vault-request-gates";
4
+ import type { AgentKind } from "../../types";
5
+ import type { MessageDto, TopicDto } from "../../types/api";
6
+ export interface RequestVaultToolContext {
7
+ userId: string;
8
+ topicId: string;
9
+ queryId?: string;
10
+ agent: AgentKind;
11
+ model?: string;
12
+ threadRootId?: string;
13
+ /**
14
+ * Set when this turn's surface cannot mask text input (Telegram has no
15
+ * native password field, so anything a person types becomes a plaintext
16
+ * message that lingers in chat history). When true the tool refuses
17
+ * immediately and never creates a card, instead of asking for a secret on
18
+ * a surface that cannot protect it.
19
+ */
20
+ unsupportedSurface?: boolean;
21
+ }
22
+ export type AnswerVaultSecretRequestResult = {
23
+ ok: true;
24
+ queryId?: string;
25
+ outcome: "fulfilled" | "declined";
26
+ answerMessage: MessageDto;
27
+ } | {
28
+ ok: false;
29
+ error: string;
30
+ };
31
+ export interface RequestVaultRuntimeHost {
32
+ messaging: {
33
+ persistence: {
34
+ getMessage(topicId: string, messageId: string): MessageDto | null | undefined;
35
+ appendMessage(message: MessageDto): void;
36
+ };
37
+ publication: {
38
+ publishMessage(topicId: string, message: MessageDto): void;
39
+ publishCardUpdate(update: VaultRequestGateCardUpdate): void;
40
+ };
41
+ };
42
+ topics: {
43
+ getTopic(topicId: string): Pick<TopicDto, "participants"> | null | undefined;
44
+ getConfig(topicId: string): {
45
+ model?: string;
46
+ } | undefined;
47
+ };
48
+ vault: {
49
+ hasKey(userId: string, key: string): boolean;
50
+ /** Writes the secret. Called before the gate is claimed, so a storage
51
+ * failure never leaves a card marked "fulfilled" without a stored value. */
52
+ set(userId: string, key: string, value: string, description: string): void;
53
+ };
54
+ durability: {
55
+ gates: {
56
+ prepare(args: {
57
+ gateId: string;
58
+ topicId: string;
59
+ queryId?: string;
60
+ idempotencyKey: string;
61
+ bodyHash: string;
62
+ messageId: string;
63
+ ownerId: string;
64
+ now: string;
65
+ }): PrepareVaultRequestGateResult;
66
+ claimAndAnswer(args: {
67
+ topicId: string;
68
+ messageId: string;
69
+ outcome: "fulfilled" | "declined";
70
+ userId: string;
71
+ ownerId: string;
72
+ source: string;
73
+ now: string;
74
+ }): ClaimVaultRequestGateResult;
75
+ cancel(topicId: string, messageId: string, ownerId: string, now: string): VaultRequestGateCardUpdate | null;
76
+ quarantine(gateId: string, ownerId: string, now: string): VaultRequestGateCardUpdate | null;
77
+ quarantineForeign(liveOwnerIds: ReadonlySet<string>, now: string): VaultRequestGateCardUpdate[];
78
+ };
79
+ processLeases: {
80
+ acquire(role: string, ownerId: string): RuntimeProcessLeaseHandle | null;
81
+ list(rolePrefix: string): RuntimeProcessLease[];
82
+ isAlive(lease: RuntimeProcessLease): boolean;
83
+ removeDead(rolePrefix: string): void;
84
+ };
85
+ };
86
+ runtime: {
87
+ ownerId: string;
88
+ createId(): string;
89
+ now(): string;
90
+ };
91
+ }
92
+ export interface RequestVaultRuntime {
93
+ startGateOwner(): void;
94
+ stopGateOwner(): void;
95
+ reconcilePendingGates(): number;
96
+ answerPendingRequest(topicId: string, messageId: string, userId: string, value: string | null): AnswerVaultSecretRequestResult;
97
+ cancelPendingRequests(topicId: string, queryId: string): void;
98
+ createToolDefinition(ctx: RequestVaultToolContext): SharedMcpTool;
99
+ }
100
+ /**
101
+ * Create an isolated request-vault-secret lifecycle over host-provided
102
+ * messaging, topic, vault, durability, and runtime services. Mirrors
103
+ * `createAskUserRuntime`'s durable-gate shape, but the thing being
104
+ * exchanged is "did the user supply a value", never the value itself.
105
+ */
106
+ export declare function createRequestVaultRuntime(host: RequestVaultRuntimeHost): RequestVaultRuntime;
107
+ export declare const defaultRequestVaultDurabilityHost: RequestVaultRuntimeHost["durability"];
108
+ export declare function startRequestVaultGateOwner(): void;
109
+ export declare function stopRequestVaultGateOwner(): void;
110
+ export declare function reconcilePendingRequestVaultGates(): number;
111
+ /**
112
+ * Host-neutral answer path for pending vault-request cards. Terminal and
113
+ * Otium should call this rather than reimplementing pending-map and
114
+ * persistence ordering. `value: null` means the user declined; any other
115
+ * string is the secret, stored via `vaultSet` before the gate is claimed,
116
+ * and never echoed back in the result.
117
+ */
118
+ export declare function answerPendingVaultSecretRequest(topicId: string, messageId: string, userId: string, value: string | null): AnswerVaultSecretRequestResult;
119
+ export declare function cancelPendingVaultSecretRequests(topicId: string, queryId: string): void;
120
+ export declare function createRequestVaultToolDefinition(ctx: RequestVaultToolContext): SharedMcpTool;
@@ -20,6 +20,7 @@ export interface ApiMessageRow {
20
20
  ask_user_question: string | null;
21
21
  tell_card: string | null;
22
22
  subagent_card: string | null;
23
+ vault_secret_request: string | null;
23
24
  mentions: string | null;
24
25
  thread_root_id: string | null;
25
26
  created_at: string;
@@ -0,0 +1,69 @@
1
+ import type { VaultSecretRequestDto } from "../types/api";
2
+ export type VaultRequestGateState = "pending" | "claimed" | "answered" | "cancelled" | "quarantined";
3
+ export interface VaultRequestGateRecord {
4
+ gateId: string;
5
+ topicId: string;
6
+ queryId?: string;
7
+ idempotencyKey: string;
8
+ bodyHash: string;
9
+ messageId: string;
10
+ ownerId: string;
11
+ state: VaultRequestGateState;
12
+ outcome?: "fulfilled" | "declined";
13
+ answeredBy?: string;
14
+ }
15
+ export interface VaultRequestGateCardUpdate {
16
+ topicId: string;
17
+ messageId: string;
18
+ vaultSecretRequest: VaultSecretRequestDto;
19
+ editedAt: string;
20
+ }
21
+ export type PrepareVaultRequestGateResult = {
22
+ outcome: "created";
23
+ gate: VaultRequestGateRecord;
24
+ } | {
25
+ outcome: "pending";
26
+ gate: VaultRequestGateRecord;
27
+ } | {
28
+ outcome: "replay";
29
+ gate: VaultRequestGateRecord;
30
+ } | {
31
+ outcome: "conflict";
32
+ gate: VaultRequestGateRecord;
33
+ };
34
+ export declare function prepareVaultRequestGate(args: {
35
+ gateId: string;
36
+ topicId: string;
37
+ queryId?: string;
38
+ idempotencyKey: string;
39
+ bodyHash: string;
40
+ messageId: string;
41
+ ownerId: string;
42
+ now: string;
43
+ }): PrepareVaultRequestGateResult;
44
+ export declare function quarantineVaultRequestGate(gateId: string, ownerId: string, now?: string): VaultRequestGateCardUpdate | null;
45
+ export declare function quarantineForeignVaultRequestGates(liveOwnerIds: ReadonlySet<string>, now?: string): VaultRequestGateCardUpdate[];
46
+ export type ClaimVaultRequestGateResult = {
47
+ outcome: "claimed";
48
+ gate: VaultRequestGateRecord;
49
+ vaultSecretRequest: VaultSecretRequestDto;
50
+ editedAt: string;
51
+ } | {
52
+ outcome: "unavailable";
53
+ };
54
+ /**
55
+ * Claim the gate and mark the card's outcome. This never touches the secret
56
+ * value itself — the caller is responsible for writing to the vault (via
57
+ * `vaultSet`) *before* calling this, so the card only ever reflects
58
+ * "fulfilled"/"declined", never the plaintext.
59
+ */
60
+ export declare function claimVaultRequestGateAndAnswer(args: {
61
+ topicId: string;
62
+ messageId: string;
63
+ outcome: "fulfilled" | "declined";
64
+ userId: string;
65
+ ownerId: string;
66
+ source: string;
67
+ now: string;
68
+ }): ClaimVaultRequestGateResult;
69
+ export declare function cancelVaultRequestGate(topicId: string, messageId: string, ownerId: string, now?: string): VaultRequestGateCardUpdate | null;
@@ -249,8 +249,9 @@ export interface MessageDto {
249
249
  threadLastReplyAt?: string;
250
250
  /** Emoji reactions, one entry per (user, emoji). */
251
251
  reactions?: ReactionDto[];
252
- kind?: "message" | "system" | "tool" | "ask_user_question" | "subagent" | "tell";
252
+ kind?: "message" | "system" | "tool" | "ask_user_question" | "vault_secret_request" | "subagent" | "tell";
253
253
  askUserQuestion?: AskUserQuestionDto;
254
+ vaultSecretRequest?: VaultSecretRequestDto;
254
255
  subagentCard?: SubagentCardDto;
255
256
  tellCard?: TellCardDto;
256
257
  createdAt: string;
@@ -264,6 +265,18 @@ export interface AskUserQuestionDto {
264
265
  selectedLabel?: string;
265
266
  expired?: boolean;
266
267
  }
268
+ /**
269
+ * Blocking card for `request_vault_secret`: the agent proposes a key and
270
+ * description, a person types only the value on a surface that can mask
271
+ * input, and the plaintext never flows back through this DTO, a tool
272
+ * result, or chat history — only the outcome does.
273
+ */
274
+ export interface VaultSecretRequestDto {
275
+ key: string;
276
+ description?: string;
277
+ status: "pending" | "fulfilled" | "declined" | "expired";
278
+ answeredBy?: string;
279
+ }
267
280
  /** Structured cross-session delivery. Never inferred from system-message text. */
268
281
  export interface TellCardDto {
269
282
  fromLabel: string;
@@ -461,6 +474,7 @@ export type WsServerMessage = {
461
474
  editedAt?: string;
462
475
  usage?: MessageTokenUsage;
463
476
  askUserQuestion?: AskUserQuestionDto;
477
+ vaultSecretRequest?: VaultSecretRequestDto;
464
478
  subagentCard?: SubagentCardDto;
465
479
  } | {
466
480
  type: "reaction_update";
@@ -1 +1 @@
1
- export declare const NEGOTIUM_VERSION = "0.22.2";
1
+ export declare const NEGOTIUM_VERSION = "0.22.4";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "negotium",
3
- "version": "0.22.2",
3
+ "version": "0.22.4",
4
4
  "type": "module",
5
5
  "description": "Install the Negotium multi-agent runtime and CLI with one package",
6
6
  "license": "Apache-2.0",