@punica/editor 1.39.1 → 1.41.1
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/index.bundle.esm.js +2 -2
- package/dist/index.bundle.esm.js.map +1 -1
- package/dist/index.bundle.umd.js +2 -2
- package/dist/index.bundle.umd.js.map +1 -1
- package/package.json +1 -1
- package/types/punica.module.kernel.ai.d.ts +92 -2
- package/types/punica.module.kernel.policy.d.ts +44 -1
- package/types/punica.module.runtime.capabilities.d.ts +7 -0
- package/types/punica.module.runtime.llm.d.ts +16 -0
- package/types/punica.module.shell.profile.d.ts +14 -4
- package/types/punica.module.shell.views.d.ts +7 -0
package/package.json
CHANGED
|
@@ -60,6 +60,12 @@ declare module 'punica' {
|
|
|
60
60
|
* to a name, not to an action.
|
|
61
61
|
*/
|
|
62
62
|
argsPreview?: unknown;
|
|
63
|
+
/**
|
|
64
|
+
* The widest grant the rule in force accepts
|
|
65
|
+
* (`kernel.PolicyRequest.maxScope`). A card offers no wider
|
|
66
|
+
* choice, and `approvePending` clamps a wider one to it.
|
|
67
|
+
*/
|
|
68
|
+
maxScope?: ApprovalScope;
|
|
63
69
|
correlationId?: string;
|
|
64
70
|
/**
|
|
65
71
|
* Trace id of the invocation that hit the gate (an agent run id
|
|
@@ -86,6 +92,29 @@ declare module 'punica' {
|
|
|
86
92
|
* agent turn, paired with how it resolved after dispatch through
|
|
87
93
|
* the gateway.
|
|
88
94
|
*/
|
|
95
|
+
/**
|
|
96
|
+
* A person's verdict on a cell an agent wrote, as
|
|
97
|
+
* `extension-ipynb-viewer` publishes it: `ai.cellKept`,
|
|
98
|
+
* `ai.cellRejected`, `ai.cellRestored`, each `kind: 'audit'` under the
|
|
99
|
+
* trace of the call that made the cell. The kernel relays a rejection
|
|
100
|
+
* or a restore to the AI session named on the record as one user-role
|
|
101
|
+
* note (`name: 'notebook'`), so the loop's next run in that
|
|
102
|
+
* conversation knows. Contract: `docs/cell-provenance.md`.
|
|
103
|
+
*/
|
|
104
|
+
export interface CellReviewPayload {
|
|
105
|
+
path: string;
|
|
106
|
+
cellId: string;
|
|
107
|
+
kind: 'insert' | 'replace';
|
|
108
|
+
/** `origin.id` of the call that wrote the cell. */
|
|
109
|
+
originId: string;
|
|
110
|
+
runId: string;
|
|
111
|
+
traceId: string;
|
|
112
|
+
/** The conversation the call came from; absent means nobody is told. */
|
|
113
|
+
sessionId?: string;
|
|
114
|
+
/** Where the cell sat, 0-based. */
|
|
115
|
+
index: number;
|
|
116
|
+
}
|
|
117
|
+
|
|
89
118
|
export interface AgentToolCall {
|
|
90
119
|
/** Provider-supplied call id; correlates the result back to the call. */
|
|
91
120
|
id: string;
|
|
@@ -109,6 +138,21 @@ declare module 'punica' {
|
|
|
109
138
|
* auto-corrected.
|
|
110
139
|
*/
|
|
111
140
|
repaired?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* True when a person edited the arguments on the approval card
|
|
143
|
+
* before the call ran (`ai.editPendingArguments`). `arguments` are
|
|
144
|
+
* then the person's, merged over the model's raw call by the rule
|
|
145
|
+
* in `approvalManagement.ts`, and the model is told so in the tool
|
|
146
|
+
* result it reads next.
|
|
147
|
+
*/
|
|
148
|
+
edited?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* With `edited`: the fields the person changed, as they typed them
|
|
151
|
+
* over the redacted preview. A field they removed is absent. Never
|
|
152
|
+
* the merged raw call, so a masked value they left alone stays out
|
|
153
|
+
* of every transcript this reaches.
|
|
154
|
+
*/
|
|
155
|
+
editedFields?: Record<string, unknown>;
|
|
112
156
|
}
|
|
113
157
|
|
|
114
158
|
/**
|
|
@@ -143,8 +187,13 @@ declare module 'punica' {
|
|
|
143
187
|
* reader a tree of ghosts. So a failed turn is a node that says
|
|
144
188
|
* what happened to it rather than a node that is missing.
|
|
145
189
|
*/
|
|
146
|
-
|
|
147
|
-
|
|
190
|
+
/**
|
|
191
|
+
* `blocked` when the turn's own model call was refused by a rule or
|
|
192
|
+
* held for a person nobody answered (1.41.0): a refusal is not an
|
|
193
|
+
* error, and the run then finishes `blocked`.
|
|
194
|
+
*/
|
|
195
|
+
outcome?: 'error' | 'cancelled' | 'blocked';
|
|
196
|
+
/** The failure text, when `outcome` is `'error'` or `'blocked'`. */
|
|
148
197
|
error?: string;
|
|
149
198
|
}
|
|
150
199
|
|
|
@@ -286,6 +335,21 @@ declare module 'punica' {
|
|
|
286
335
|
| 'blocked'
|
|
287
336
|
| 'error';
|
|
288
337
|
|
|
338
|
+
/**
|
|
339
|
+
* How free one run is, chosen per run by the person who starts it.
|
|
340
|
+
*
|
|
341
|
+
* The stance acts on exactly one rule of the gate — the agent-mode
|
|
342
|
+
* profile that holds an AI actor's writes and high-risk calls for a
|
|
343
|
+
* person (`docs/approvals.md`) — and on nothing in
|
|
344
|
+
* `.punica/policy.yaml`, whose `deny` and `require` hold in every
|
|
345
|
+
* stance. `ask` offers the model no tools at all; `observe` refuses
|
|
346
|
+
* what the profile would have held, since a run that only looks has
|
|
347
|
+
* nobody to ask; `assist` is the profile as it stands, and what an
|
|
348
|
+
* absent stance means; `auto` skips the profile, so a write runs on
|
|
349
|
+
* its own unless a rule or the capability's own declaration holds it.
|
|
350
|
+
*/
|
|
351
|
+
export type AgentStance = 'ask' | 'observe' | 'assist' | 'auto';
|
|
352
|
+
|
|
289
353
|
/**
|
|
290
354
|
* Input to a single agent run. The catalog the model may call is
|
|
291
355
|
* narrowed by `toolFilter` (Faz 2 ships a curated subset; the full
|
|
@@ -325,6 +389,24 @@ declare module 'punica' {
|
|
|
325
389
|
* could join them. Contract: `docs/agent-loops.md`.
|
|
326
390
|
*/
|
|
327
391
|
trace?: { traceId: string; parentSpanId?: string };
|
|
392
|
+
/**
|
|
393
|
+
* The run's stance (see {@link AgentStance}). Omitted ⇒ `assist`,
|
|
394
|
+
* which is what every run was before stances existed. Recorded on
|
|
395
|
+
* `ai.agentStarted` and carried to the gate on the run's policy
|
|
396
|
+
* context, so the trail says under which stance a call was decided.
|
|
397
|
+
*/
|
|
398
|
+
stance?: AgentStance;
|
|
399
|
+
/**
|
|
400
|
+
* The AI core that answers this run, in the form `llms.activeCore`
|
|
401
|
+
* writes: `local:<id>` or `remote:<id>`. Omitted ⇒ the active core,
|
|
402
|
+
* exactly as before. Carried on every model call of the run as the
|
|
403
|
+
* request's `providerId`, so the host dispatches to that core (a
|
|
404
|
+
* remote one through the directory `extension-llms` publishes as
|
|
405
|
+
* `llm.remote.routes`) and the egress guard judges the run by it;
|
|
406
|
+
* recorded on `ai.agentStarted` as `coreId`. One model per task is
|
|
407
|
+
* this field (Agent Mode §9, `docs/agent-loops.md`).
|
|
408
|
+
*/
|
|
409
|
+
coreId?: string;
|
|
328
410
|
/**
|
|
329
411
|
* Optional capability catalog filter (mirrors
|
|
330
412
|
* `capability.schemaExport`'s filter shape). When omitted, the
|
|
@@ -680,6 +762,14 @@ declare module 'punica' {
|
|
|
680
762
|
getPendingApprovals(): PendingApproval[];
|
|
681
763
|
approvePending(pendingId: string, scope: kernel.ApprovalScope): boolean;
|
|
682
764
|
dismissPending(pendingId: string): boolean;
|
|
765
|
+
/**
|
|
766
|
+
* Hand a pending question back with different arguments. No grant
|
|
767
|
+
* and no decline is written; the loop that asked dispatches again
|
|
768
|
+
* with the person's arguments and the gate asks anew, so an edit is
|
|
769
|
+
* a new question (a new `argsBinding`) and never an edited grant.
|
|
770
|
+
* Refused (`false`) when `edited` is not a plain object.
|
|
771
|
+
*/
|
|
772
|
+
editPending(pendingId: string, edited: unknown): boolean;
|
|
683
773
|
/**
|
|
684
774
|
* Run the agentic tool-use loop: the model repeatedly decides on
|
|
685
775
|
* capabilities to call as tools, the loop dispatches them through
|
|
@@ -30,6 +30,14 @@ declare module 'punica' {
|
|
|
30
30
|
* key exactly as they did before actions existed.
|
|
31
31
|
*/
|
|
32
32
|
action?: CapabilityAction[];
|
|
33
|
+
/**
|
|
34
|
+
* `'remote'` when the guarded call's payload would leave this
|
|
35
|
+
* machine, as the gateway's `egressGuard` resolved it before the
|
|
36
|
+
* gate asked. Absent for a call that stays here and for every
|
|
37
|
+
* request with no capability behind it. A rule with `egress:
|
|
38
|
+
* remote` reaches exactly the requests that carry this.
|
|
39
|
+
*/
|
|
40
|
+
egress?: 'remote';
|
|
33
41
|
risk: PolicyRisk;
|
|
34
42
|
approval: PolicyApproval;
|
|
35
43
|
/**
|
|
@@ -57,6 +65,13 @@ declare module 'punica' {
|
|
|
57
65
|
* user consented to a hash they never saw.
|
|
58
66
|
*/
|
|
59
67
|
argsPreview?: unknown;
|
|
68
|
+
/**
|
|
69
|
+
* The widest grant the rule in force accepts, set by the gate from
|
|
70
|
+
* the decision before it asks (`PolicyDecision.maxScope`) so the
|
|
71
|
+
* prompt offers no wider button and `approvePending` records no
|
|
72
|
+
* wider grant. Absent means the approver chooses.
|
|
73
|
+
*/
|
|
74
|
+
maxScope?: ApprovalScope;
|
|
60
75
|
}
|
|
61
76
|
|
|
62
77
|
/**
|
|
@@ -188,6 +203,12 @@ declare module 'punica' {
|
|
|
188
203
|
mode: PolicyMode;
|
|
189
204
|
requiresApproval: boolean;
|
|
190
205
|
suggestedScope?: ApprovalScope;
|
|
206
|
+
/**
|
|
207
|
+
* The widest grant the deciding `require` rule accepts (its
|
|
208
|
+
* `scope:`). Grants wider than this were not consulted. Absent
|
|
209
|
+
* when no rule wrote one.
|
|
210
|
+
*/
|
|
211
|
+
maxScope?: ApprovalScope;
|
|
191
212
|
reason?: string;
|
|
192
213
|
/**
|
|
193
214
|
* Set when a rule from a policy template decided this. Absent
|
|
@@ -460,11 +481,31 @@ declare module 'punica' {
|
|
|
460
481
|
* `docs/capability-actions.md`.
|
|
461
482
|
*/
|
|
462
483
|
action?: CapabilityAction[];
|
|
484
|
+
/**
|
|
485
|
+
* Selects the calls whose payload would leave this machine — a
|
|
486
|
+
* model call bound for a remote provider, a capability declaring
|
|
487
|
+
* `net.request` — as the gate resolved it. `deny egress: remote`
|
|
488
|
+
* is the sentence "no data leaves this machine" for every governed
|
|
489
|
+
* call; the direct model door is governed by `kind: llm.remote`
|
|
490
|
+
* (`docs/sensitive-data-egress.md`). The only value is `remote`.
|
|
491
|
+
*/
|
|
492
|
+
egress?: 'remote';
|
|
463
493
|
effect: PolicyRuleEffect;
|
|
464
494
|
/** ANDed. Absent or empty matches every argument tuple. */
|
|
465
495
|
when?: PolicyCondition[];
|
|
466
496
|
/** Which approval `effect: 'require'` demands. Default `step`. */
|
|
467
497
|
approval?: 'none' | 'plan' | 'step';
|
|
498
|
+
/**
|
|
499
|
+
* The widest grant that satisfies this rule, only on
|
|
500
|
+
* `effect: 'require'`. `once` means every call is asked about;
|
|
501
|
+
* `workspace` lets a project-wide grant stand and ignores an
|
|
502
|
+
* `always`; absent is `always`, which is what every rule written
|
|
503
|
+
* before this field meant — the approver chooses. An approver may
|
|
504
|
+
* go below the rule's scope and never above it: a wider grant on
|
|
505
|
+
* the store is simply not consulted, so tightening a rule takes
|
|
506
|
+
* effect on the next call without anyone revoking anything.
|
|
507
|
+
*/
|
|
508
|
+
scope?: ApprovalScope;
|
|
468
509
|
/** Shown to the user on a denial and written into the audit record. */
|
|
469
510
|
reason?: string;
|
|
470
511
|
}
|
|
@@ -477,6 +518,8 @@ declare module 'punica' {
|
|
|
477
518
|
ruleIndex: number;
|
|
478
519
|
effect: PolicyRuleEffect;
|
|
479
520
|
reason?: string;
|
|
521
|
+
/** The rule's `scope`, when it wrote one (`effect: require` only). */
|
|
522
|
+
scope?: ApprovalScope;
|
|
480
523
|
/** Digest of the template's rules — which policy text was in force. */
|
|
481
524
|
digest?: string;
|
|
482
525
|
/**
|
|
@@ -484,7 +527,7 @@ declare module 'punica' {
|
|
|
484
527
|
* declares. A reader of the audit record can otherwise not tell
|
|
485
528
|
* why a rule naming no id applied to this call.
|
|
486
529
|
*/
|
|
487
|
-
matchedBy?: 'id' | 'action';
|
|
530
|
+
matchedBy?: 'id' | 'action' | 'egress';
|
|
488
531
|
}
|
|
489
532
|
|
|
490
533
|
/** A rule that matched, plus the rule itself for the caller to read. */
|
|
@@ -61,6 +61,13 @@ declare module 'punica' {
|
|
|
61
61
|
mode: 'suggest' | 'execute';
|
|
62
62
|
/** Approval token (if approval was granted) */
|
|
63
63
|
approvalToken?: string;
|
|
64
|
+
/**
|
|
65
|
+
* The agent run's stance, set by the kernel loop from
|
|
66
|
+
* `AgentRunInput.stance` and read by the gate's agent-mode rule alone
|
|
67
|
+
* (`kernel.AI.AgentStance`). Meaningful only for an `ai` actor; absent
|
|
68
|
+
* means the profile as it stands.
|
|
69
|
+
*/
|
|
70
|
+
stance?: 'ask' | 'observe' | 'assist' | 'auto';
|
|
64
71
|
}
|
|
65
72
|
|
|
66
73
|
/**
|
|
@@ -423,6 +423,18 @@ declare module 'punica' {
|
|
|
423
423
|
* this to gate which dispatches the provider can serve.
|
|
424
424
|
*/
|
|
425
425
|
capabilities: Set<LlmProviderCapability>;
|
|
426
|
+
/**
|
|
427
|
+
* Where a request would run, said BEFORE dispatch: `'local'` when
|
|
428
|
+
* the answer stays on this machine, `'remote'` when it leaves it,
|
|
429
|
+
* nothing when the provider cannot say. Read by the facade's remote
|
|
430
|
+
* gate and the gateway's `egressGuard` after the request's own
|
|
431
|
+
* `route` / `providerId` and before the provider's `id`; a provider
|
|
432
|
+
* that says nothing is judged by its id, and one with no id either
|
|
433
|
+
* is treated as remote (`docs/sensitive-data-egress.md`).
|
|
434
|
+
*/
|
|
435
|
+
describeDestination?(
|
|
436
|
+
req: LlmChatRequest
|
|
437
|
+
): 'local' | 'remote' | undefined | Promise<'local' | 'remote' | undefined>;
|
|
426
438
|
chat(req: LlmChatRequest): Promise<LlmChatResponse>;
|
|
427
439
|
/**
|
|
428
440
|
* Streaming chat. Optional — providers that don't support
|
|
@@ -608,6 +620,10 @@ declare module 'punica' {
|
|
|
608
620
|
|
|
609
621
|
export interface LlmApi {
|
|
610
622
|
chat(req: LlmChatRequest): Promise<LlmChatResponse>;
|
|
623
|
+
/** See `LlmProvider.describeDestination`; a host registers an `LlmApi`. */
|
|
624
|
+
describeDestination?(
|
|
625
|
+
req: LlmChatRequest
|
|
626
|
+
): 'local' | 'remote' | undefined | Promise<'local' | 'remote' | undefined>;
|
|
611
627
|
/**
|
|
612
628
|
* Optional streaming chat. Hosts that back a streaming-capable
|
|
613
629
|
* provider expose it here; the substrate runtime facade wraps it
|
|
@@ -163,10 +163,20 @@ declare module 'punica' {
|
|
|
163
163
|
* during bootstrap. Kernel and runtime modules are always registered
|
|
164
164
|
* unconditionally.
|
|
165
165
|
*
|
|
166
|
-
* Structural DOM slots are derived from this list
|
|
167
|
-
*
|
|
168
|
-
* - `shell.
|
|
169
|
-
*
|
|
166
|
+
* Structural DOM slots are derived from this list
|
|
167
|
+
* (`presentedSlots()` in `@punica/editor` is the one definition):
|
|
168
|
+
* - `shell.activityBar` → `activityBar`, `primarySidebar` and
|
|
169
|
+
* `contentSidebar` — the strip is the only gesture that opens a
|
|
170
|
+
* primary sidebar, and the content drawer is anchored beside it
|
|
171
|
+
* (until 2026-09-26 the two sidebars followed `shell.view`, which
|
|
172
|
+
* every profile activates for its helpers, so a window with no
|
|
173
|
+
* strip got a sidebar nothing could open)
|
|
174
|
+
* - `shell.statusbar` → `statusbar`
|
|
175
|
+
*
|
|
176
|
+
* A view whose declared home slot the profile does not present is
|
|
177
|
+
* placed as a tab in the `content` slot, on demand — the extension
|
|
178
|
+
* analysis decorator applies that rule, so an extension never reads
|
|
179
|
+
* the profile.
|
|
170
180
|
*/
|
|
171
181
|
activeModules: ShellModuleId[];
|
|
172
182
|
/**
|
|
@@ -12,6 +12,13 @@ declare module 'punica' {
|
|
|
12
12
|
* agents and MCP clients all converge on them).
|
|
13
13
|
*/
|
|
14
14
|
export namespace Views {
|
|
15
|
+
/**
|
|
16
|
+
* Where a view can be placed. `content` is never a manifest home: it is
|
|
17
|
+
* where a view lands when the active profile presents none of the slot
|
|
18
|
+
* its manifest names (`homeSlot` keeps the declared one), and a view
|
|
19
|
+
* placed there is a content tab, opened by a reveal and closed like a
|
|
20
|
+
* document.
|
|
21
|
+
*/
|
|
15
22
|
export type ViewSlotId =
|
|
16
23
|
| 'primarySidebar'
|
|
17
24
|
| 'secondarySidebar'
|