@particle-academy/prism-acp 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -15
- package/dist/acp/agent.d.ts +17 -4
- package/dist/acp/agent.js +23 -9
- package/dist/acp/stdio.js +15 -5
- package/dist/codex/driver.d.ts +29 -0
- package/dist/codex/driver.js +1081 -0
- package/dist/codex/rate-limit.d.ts +32 -0
- package/dist/codex/rate-limit.js +129 -0
- package/dist/codex/transport.d.ts +24 -0
- package/dist/codex/transport.js +90 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +3 -1
- package/dist/meta.d.ts +7 -4
- package/dist/meta.js +7 -4
- package/package.json +1 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Codex's percentage-based rate-limit window. */
|
|
2
|
+
export interface CodexRateLimitWindow {
|
|
3
|
+
readonly usedPercent: number;
|
|
4
|
+
readonly windowDurationMins: number;
|
|
5
|
+
/** Epoch milliseconds, converted from Codex's epoch-second `resetsAt`. */
|
|
6
|
+
readonly resetsAtMs: number;
|
|
7
|
+
}
|
|
8
|
+
export interface CodexRateLimit {
|
|
9
|
+
readonly ordinaryUsageAllowed: boolean | null;
|
|
10
|
+
readonly planType?: string;
|
|
11
|
+
readonly primary: CodexRateLimitWindow | null;
|
|
12
|
+
readonly secondary: CodexRateLimitWindow | null;
|
|
13
|
+
readonly credits?: {
|
|
14
|
+
readonly hasCredits: boolean;
|
|
15
|
+
readonly unlimited: boolean;
|
|
16
|
+
readonly balance: number | null;
|
|
17
|
+
};
|
|
18
|
+
readonly spendControlReached?: boolean | null;
|
|
19
|
+
readonly rateLimitReachedType?: string | null;
|
|
20
|
+
readonly availableResetCredits?: number;
|
|
21
|
+
}
|
|
22
|
+
export type CodexRateLimitRead = {
|
|
23
|
+
readonly ok: true;
|
|
24
|
+
readonly limit: CodexRateLimit;
|
|
25
|
+
} | {
|
|
26
|
+
readonly ok: false;
|
|
27
|
+
readonly reason: string;
|
|
28
|
+
};
|
|
29
|
+
/** Read the allow-listed rate-limit fields; identifiers and unknown fields never pass through. */
|
|
30
|
+
export declare function readCodexRateLimit(value: unknown): CodexRateLimitRead;
|
|
31
|
+
export declare function parseCodexRateLimit(value: unknown): CodexRateLimit | undefined;
|
|
32
|
+
export declare function codexRateLimitNotice(limit: CodexRateLimit): string;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
function isObject(value) {
|
|
2
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
function describe(value) {
|
|
5
|
+
if (value === null)
|
|
6
|
+
return 'null';
|
|
7
|
+
if (value === undefined)
|
|
8
|
+
return 'undefined';
|
|
9
|
+
if (typeof value === 'string')
|
|
10
|
+
return `string(${value.length})`;
|
|
11
|
+
if (typeof value === 'number' || typeof value === 'boolean')
|
|
12
|
+
return String(value);
|
|
13
|
+
if (Array.isArray(value))
|
|
14
|
+
return `array(${value.length})`;
|
|
15
|
+
return typeof value === 'object' ? 'object' : typeof value;
|
|
16
|
+
}
|
|
17
|
+
function refuse(path, expected, got) {
|
|
18
|
+
return { ok: false, reason: `codex_rate_limit: ${path} expected ${expected}, got ${describe(got)}` };
|
|
19
|
+
}
|
|
20
|
+
function finite(value, min) {
|
|
21
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= min;
|
|
22
|
+
}
|
|
23
|
+
function readWindow(value, path) {
|
|
24
|
+
if (value === null)
|
|
25
|
+
return null;
|
|
26
|
+
if (!isObject(value))
|
|
27
|
+
return refuse(path, 'an object or null', value);
|
|
28
|
+
if (!finite(value.usedPercent, 0)) {
|
|
29
|
+
return refuse(`${path}.usedPercent`, 'finite number >= 0', value.usedPercent);
|
|
30
|
+
}
|
|
31
|
+
const windowDurationMins = value.windowDurationMins;
|
|
32
|
+
if (typeof windowDurationMins !== 'number' || !Number.isSafeInteger(windowDurationMins) || windowDurationMins < 1) {
|
|
33
|
+
return refuse(`${path}.windowDurationMins`, 'safe integer >= 1', value.windowDurationMins);
|
|
34
|
+
}
|
|
35
|
+
if (!finite(value.resetsAt, Number.MIN_VALUE)) {
|
|
36
|
+
return refuse(`${path}.resetsAt`, 'finite number > 0 (epoch seconds)', value.resetsAt);
|
|
37
|
+
}
|
|
38
|
+
const resetsAtMs = value.resetsAt * 1000;
|
|
39
|
+
if (!Number.isFinite(resetsAtMs) || resetsAtMs > 8.64e15) {
|
|
40
|
+
return refuse(`${path}.resetsAt`, 'valid epoch seconds representable as a JavaScript date', value.resetsAt);
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
usedPercent: value.usedPercent,
|
|
44
|
+
windowDurationMins,
|
|
45
|
+
resetsAtMs,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** Read the allow-listed rate-limit fields; identifiers and unknown fields never pass through. */
|
|
49
|
+
export function readCodexRateLimit(value) {
|
|
50
|
+
if (!isObject(value))
|
|
51
|
+
return refuse('payload', 'an object', value);
|
|
52
|
+
const outer = value;
|
|
53
|
+
const rates = isObject(value.rateLimits) ? value.rateLimits : value;
|
|
54
|
+
const ordinaryUsageAllowed = outer.ordinaryUsageAllowed ?? rates.ordinaryUsageAllowed ?? null;
|
|
55
|
+
if (ordinaryUsageAllowed !== null && typeof ordinaryUsageAllowed !== 'boolean') {
|
|
56
|
+
return refuse('ordinaryUsageAllowed', 'boolean or null', ordinaryUsageAllowed);
|
|
57
|
+
}
|
|
58
|
+
const primary = readWindow(rates.primary, 'rateLimits.primary');
|
|
59
|
+
if (primary !== null && 'ok' in primary && primary.ok === false)
|
|
60
|
+
return primary;
|
|
61
|
+
const secondary = readWindow(rates.secondary, 'rateLimits.secondary');
|
|
62
|
+
if (secondary !== null && 'ok' in secondary && secondary.ok === false)
|
|
63
|
+
return secondary;
|
|
64
|
+
let credits;
|
|
65
|
+
if (rates.credits !== undefined && rates.credits !== null) {
|
|
66
|
+
if (!isObject(rates.credits))
|
|
67
|
+
return refuse('rateLimits.credits', 'an object or null', rates.credits);
|
|
68
|
+
const { hasCredits, unlimited, balance } = rates.credits;
|
|
69
|
+
if (typeof hasCredits !== 'boolean') {
|
|
70
|
+
return refuse('rateLimits.credits.hasCredits', 'boolean', hasCredits);
|
|
71
|
+
}
|
|
72
|
+
if (typeof unlimited !== 'boolean') {
|
|
73
|
+
return refuse('rateLimits.credits.unlimited', 'boolean', unlimited);
|
|
74
|
+
}
|
|
75
|
+
if (balance !== undefined && balance !== null && !finite(balance, 0)) {
|
|
76
|
+
return refuse('rateLimits.credits.balance', 'finite number >= 0 or null', balance);
|
|
77
|
+
}
|
|
78
|
+
credits = { hasCredits, unlimited, balance: typeof balance === 'number' ? balance : null };
|
|
79
|
+
}
|
|
80
|
+
if (rates.planType !== undefined && typeof rates.planType !== 'string') {
|
|
81
|
+
return refuse('rateLimits.planType', 'string', rates.planType);
|
|
82
|
+
}
|
|
83
|
+
const planType = typeof rates.planType === 'string' ? rates.planType : undefined;
|
|
84
|
+
if (rates.spendControlReached !== undefined &&
|
|
85
|
+
rates.spendControlReached !== null &&
|
|
86
|
+
typeof rates.spendControlReached !== 'boolean') {
|
|
87
|
+
return refuse('rateLimits.spendControlReached', 'boolean or null', rates.spendControlReached);
|
|
88
|
+
}
|
|
89
|
+
const spendControlReached = typeof rates.spendControlReached === 'boolean' || rates.spendControlReached === null
|
|
90
|
+
? rates.spendControlReached
|
|
91
|
+
: undefined;
|
|
92
|
+
if (rates.rateLimitReachedType !== undefined &&
|
|
93
|
+
rates.rateLimitReachedType !== null &&
|
|
94
|
+
typeof rates.rateLimitReachedType !== 'string') {
|
|
95
|
+
return refuse('rateLimits.rateLimitReachedType', 'string or null', rates.rateLimitReachedType);
|
|
96
|
+
}
|
|
97
|
+
const rateLimitReachedType = typeof rates.rateLimitReachedType === 'string' || rates.rateLimitReachedType === null
|
|
98
|
+
? rates.rateLimitReachedType
|
|
99
|
+
: undefined;
|
|
100
|
+
const resetCredits = isObject(outer.rateLimitResetCredits)
|
|
101
|
+
? outer.rateLimitResetCredits.availableCount
|
|
102
|
+
: undefined;
|
|
103
|
+
if (resetCredits !== undefined && (!Number.isSafeInteger(resetCredits) || resetCredits < 0)) {
|
|
104
|
+
return refuse('rateLimitResetCredits.availableCount', 'integer >= 0', resetCredits);
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
ok: true,
|
|
108
|
+
limit: {
|
|
109
|
+
ordinaryUsageAllowed: ordinaryUsageAllowed,
|
|
110
|
+
...(planType === undefined ? {} : { planType }),
|
|
111
|
+
primary: primary,
|
|
112
|
+
secondary: secondary,
|
|
113
|
+
...(credits === undefined ? {} : { credits }),
|
|
114
|
+
...(spendControlReached === undefined ? {} : { spendControlReached }),
|
|
115
|
+
...(rateLimitReachedType === undefined ? {} : { rateLimitReachedType }),
|
|
116
|
+
...(resetCredits === undefined ? {} : { availableResetCredits: resetCredits }),
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export function parseCodexRateLimit(value) {
|
|
121
|
+
const result = readCodexRateLimit(value);
|
|
122
|
+
return result.ok ? result.limit : undefined;
|
|
123
|
+
}
|
|
124
|
+
export function codexRateLimitNotice(limit) {
|
|
125
|
+
const window = limit.primary;
|
|
126
|
+
if (window === null)
|
|
127
|
+
return 'Codex rate limit usage is unavailable.';
|
|
128
|
+
return `Codex rate limit: ${window.usedPercent}% used in ${window.windowDurationMins} minutes, resets ${new Date(window.resetsAtMs).toISOString()}.`;
|
|
129
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface CodexTransportHandlers {
|
|
2
|
+
readonly onFrame: (frame: unknown) => void;
|
|
3
|
+
readonly onStderr: (line: string) => void;
|
|
4
|
+
readonly onProblem: (problem: string) => void;
|
|
5
|
+
readonly onExit: (code: number | null, signal: NodeJS.Signals | null) => void;
|
|
6
|
+
}
|
|
7
|
+
export interface CodexTransport {
|
|
8
|
+
start(): Promise<void>;
|
|
9
|
+
send(frame: unknown): void;
|
|
10
|
+
close(signal?: NodeJS.Signals): void;
|
|
11
|
+
}
|
|
12
|
+
export interface CodexTransportOptions {
|
|
13
|
+
readonly cwd: string;
|
|
14
|
+
readonly env: Readonly<Record<string, string>>;
|
|
15
|
+
readonly binary?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Run App Server over its measured, newline-framed stdio JSON-RPC channel. */
|
|
18
|
+
export declare class StdioCodexTransport implements CodexTransport {
|
|
19
|
+
#private;
|
|
20
|
+
constructor(options: CodexTransportOptions, handlers: CodexTransportHandlers);
|
|
21
|
+
start(): Promise<void>;
|
|
22
|
+
send(frame: unknown): void;
|
|
23
|
+
close(signal?: NodeJS.Signals): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { NdjsonFramer, encodeLine } from '../ndjson.js';
|
|
3
|
+
/** Run App Server over its measured, newline-framed stdio JSON-RPC channel. */
|
|
4
|
+
export class StdioCodexTransport {
|
|
5
|
+
#options;
|
|
6
|
+
#handlers;
|
|
7
|
+
#framer = new NdjsonFramer();
|
|
8
|
+
#child = null;
|
|
9
|
+
#stderrBuffer = '';
|
|
10
|
+
#closed = false;
|
|
11
|
+
#stderrOverflowReported = false;
|
|
12
|
+
constructor(options, handlers) {
|
|
13
|
+
this.#options = options;
|
|
14
|
+
this.#handlers = handlers;
|
|
15
|
+
}
|
|
16
|
+
async start() {
|
|
17
|
+
if (this.#child !== null)
|
|
18
|
+
throw new Error('Codex transport already started');
|
|
19
|
+
const major = Number(process.versions.node.split('.')[0]);
|
|
20
|
+
if (!Number.isInteger(major) || major < 22) {
|
|
21
|
+
throw new Error('Codex app-server stdio transport requires Node.js 22 or newer');
|
|
22
|
+
}
|
|
23
|
+
const child = spawn(this.#options.binary ?? 'codex', ['app-server', '--listen', 'stdio://'], {
|
|
24
|
+
cwd: this.#options.cwd,
|
|
25
|
+
env: { ...this.#options.env },
|
|
26
|
+
shell: process.platform === 'win32',
|
|
27
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
28
|
+
});
|
|
29
|
+
this.#child = child;
|
|
30
|
+
child.stdout?.on('data', (chunk) => {
|
|
31
|
+
for (const frame of this.#framer.push(chunk)) {
|
|
32
|
+
if (frame.ok)
|
|
33
|
+
this.#handlers.onFrame(frame.value);
|
|
34
|
+
else
|
|
35
|
+
this.#handlers.onProblem(frame.error.message);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
child.stderr?.setEncoding('utf8');
|
|
39
|
+
child.stderr?.on('data', (chunk) => this.#onStderr(chunk));
|
|
40
|
+
child.on('error', (cause) => this.#handlers.onProblem(`failed to spawn Codex (${cause.name})`));
|
|
41
|
+
child.on('close', (code, signal) => {
|
|
42
|
+
this.#closed = true;
|
|
43
|
+
for (const frame of this.#framer.end()) {
|
|
44
|
+
if (frame.ok)
|
|
45
|
+
this.#handlers.onFrame(frame.value);
|
|
46
|
+
else
|
|
47
|
+
this.#handlers.onProblem(frame.error.message);
|
|
48
|
+
}
|
|
49
|
+
this.#handlers.onExit(code, signal);
|
|
50
|
+
});
|
|
51
|
+
await new Promise((resolve, reject) => {
|
|
52
|
+
child.once('spawn', resolve);
|
|
53
|
+
child.once('error', (cause) => reject(new Error(`Codex app-server spawn failed (${cause.name})`)));
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
send(frame) {
|
|
57
|
+
const stdin = this.#child?.stdin;
|
|
58
|
+
if (stdin === null || stdin === undefined || stdin.destroyed || this.#closed) {
|
|
59
|
+
throw new Error('Codex app-server stdin is not open');
|
|
60
|
+
}
|
|
61
|
+
stdin.write(encodeLine(frame));
|
|
62
|
+
}
|
|
63
|
+
close(signal = 'SIGTERM') {
|
|
64
|
+
if (this.#closed)
|
|
65
|
+
return;
|
|
66
|
+
this.#closed = true;
|
|
67
|
+
this.#child?.stdin?.end();
|
|
68
|
+
this.#child?.kill(signal);
|
|
69
|
+
}
|
|
70
|
+
#onStderr(chunk) {
|
|
71
|
+
this.#stderrBuffer += chunk;
|
|
72
|
+
if (this.#stderrBuffer.length > 64_000) {
|
|
73
|
+
if (!this.#stderrOverflowReported) {
|
|
74
|
+
this.#stderrOverflowReported = true;
|
|
75
|
+
this.#handlers.onProblem('Codex stderr buffer exceeded 64000 characters');
|
|
76
|
+
}
|
|
77
|
+
this.#stderrBuffer = this.#stderrBuffer.slice(-64_000);
|
|
78
|
+
}
|
|
79
|
+
let newline;
|
|
80
|
+
while ((newline = this.#stderrBuffer.indexOf('\n')) !== -1) {
|
|
81
|
+
const line = this.#stderrBuffer.slice(0, newline).replace(/\r$/, '');
|
|
82
|
+
this.#stderrBuffer = this.#stderrBuffer.slice(newline + 1);
|
|
83
|
+
if (line.length > 0) {
|
|
84
|
+
// App Server stderr is not a public logging surface: provider output
|
|
85
|
+
// can contain account and rate-limit identifiers.
|
|
86
|
+
this.#handlers.onStderr(`Codex stderr line withheld (${line.length} characters)`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { BASE_ALLOW, OUTRANKING_CREDENTIALS, childEnv } from './env.js';
|
|
|
4
4
|
export type { ChildEnvOptions, ChildEnvResult } from './env.js';
|
|
5
5
|
export { JsonRpcPeer, RPC_INTERNAL_ERROR, RPC_INVALID_PARAMS, RPC_INVALID_REQUEST, RPC_METHOD_NOT_FOUND, RPC_PARSE_ERROR, RpcError, } from './jsonrpc.js';
|
|
6
6
|
export type { JsonRpcPeerOptions, NotificationHandler, RequestHandler, RpcId, } from './jsonrpc.js';
|
|
7
|
-
export { META_CLI_SESSION_ID, META_NS, META_RATE_LIMIT, META_THINKING_SIGNATURE, META_THINKING_TOKENS_ESTIMATE, META_UNMAPPED_FRAME, RESERVED_META_KEYS, metaKey, withMeta, } from './meta.js';
|
|
7
|
+
export { META_CLI_SESSION_ID, META_EXEC_POLICY_AMENDMENT, META_NS, META_RATE_LIMIT, META_THINKING_SIGNATURE, META_THINKING_TOKENS_ESTIMATE, META_UNMAPPED_FRAME, RESERVED_META_KEYS, metaKey, withMeta, } from './meta.js';
|
|
8
8
|
export { ClaudeToAcp } from './claude/to-acp.js';
|
|
9
9
|
export type { AcpUpdate, ToolStatus } from './claude/to-acp.js';
|
|
10
10
|
export { parseRateLimit, rateLimitNotice, readRateLimit } from './claude/rate-limit.js';
|
|
@@ -12,10 +12,14 @@ export type { ClaudeRateLimit, ClaudeRateLimitWindow, RateLimitRead } from './cl
|
|
|
12
12
|
export { ClaudeDriver, claudeArgs, promptLine, updatesFromFrames } from './claude/driver.js';
|
|
13
13
|
export type { ClaudeDriverEvents, ClaudeDriverOptions, ClaudePermissionMode, } from './claude/driver.js';
|
|
14
14
|
export { AcpAgent, PROTOCOL_VERSION } from './acp/agent.js';
|
|
15
|
-
export type { AcpAgentOptions, AgentDriver, DriverEvents, DriverFactory, SessionProbe as AcpSessionProbe, } from './acp/agent.js';
|
|
15
|
+
export type { AcpAgentOptions, AgentDriver, DriverEvents, DriverFactory, PermissionOutcome, PermissionRequest, SessionProbe as AcpSessionProbe, } from './acp/agent.js';
|
|
16
16
|
export { probeSessionStore } from './claude/session-store.js';
|
|
17
17
|
export type { SessionExistence, SessionProbe, SessionStoreOptions } from './claude/session-store.js';
|
|
18
18
|
export { serve } from './acp/stdio.js';
|
|
19
19
|
export type { Served, ServeOptions } from './acp/stdio.js';
|
|
20
20
|
export { cliSessionIdOf, turnOutcomeOf } from './claude/driver.js';
|
|
21
21
|
export type { StopReason, TurnOutcome } from './claude/driver.js';
|
|
22
|
+
export { CodexDriver } from './codex/driver.js';
|
|
23
|
+
export type { CodexDriverOptions, CodexTransportFactory } from './codex/driver.js';
|
|
24
|
+
export { codexRateLimitNotice, parseCodexRateLimit, readCodexRateLimit } from './codex/rate-limit.js';
|
|
25
|
+
export type { CodexRateLimit, CodexRateLimitRead, CodexRateLimitWindow } from './codex/rate-limit.js';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { MAX_LINE_BYTES, NdjsonFramer, encodeLine, parseLine } from './ndjson.js';
|
|
2
2
|
export { BASE_ALLOW, OUTRANKING_CREDENTIALS, childEnv } from './env.js';
|
|
3
3
|
export { JsonRpcPeer, RPC_INTERNAL_ERROR, RPC_INVALID_PARAMS, RPC_INVALID_REQUEST, RPC_METHOD_NOT_FOUND, RPC_PARSE_ERROR, RpcError, } from './jsonrpc.js';
|
|
4
|
-
export { META_CLI_SESSION_ID, META_NS, META_RATE_LIMIT, META_THINKING_SIGNATURE, META_THINKING_TOKENS_ESTIMATE, META_UNMAPPED_FRAME, RESERVED_META_KEYS, metaKey, withMeta, } from './meta.js';
|
|
4
|
+
export { META_CLI_SESSION_ID, META_EXEC_POLICY_AMENDMENT, META_NS, META_RATE_LIMIT, META_THINKING_SIGNATURE, META_THINKING_TOKENS_ESTIMATE, META_UNMAPPED_FRAME, RESERVED_META_KEYS, metaKey, withMeta, } from './meta.js';
|
|
5
5
|
export { ClaudeToAcp } from './claude/to-acp.js';
|
|
6
6
|
export { parseRateLimit, rateLimitNotice, readRateLimit } from './claude/rate-limit.js';
|
|
7
7
|
export { ClaudeDriver, claudeArgs, promptLine, updatesFromFrames } from './claude/driver.js';
|
|
@@ -9,3 +9,5 @@ export { AcpAgent, PROTOCOL_VERSION } from './acp/agent.js';
|
|
|
9
9
|
export { probeSessionStore } from './claude/session-store.js';
|
|
10
10
|
export { serve } from './acp/stdio.js';
|
|
11
11
|
export { cliSessionIdOf, turnOutcomeOf } from './claude/driver.js';
|
|
12
|
+
export { CodexDriver } from './codex/driver.js';
|
|
13
|
+
export { codexRateLimitNotice, parseCodexRateLimit, readCodexRateLimit } from './codex/rate-limit.js';
|
package/dist/meta.d.ts
CHANGED
|
@@ -69,15 +69,18 @@ export declare const META_THINKING_SIGNATURE: string;
|
|
|
69
69
|
export declare const META_THINKING_TOKENS_ESTIMATE: string;
|
|
70
70
|
/** Structured rate-limit detail, alongside the human-readable notice. */
|
|
71
71
|
export declare const META_RATE_LIMIT: string;
|
|
72
|
+
/** A command-line approval's persistent execpolicy amendment, tied to its ACP option. */
|
|
73
|
+
export declare const META_EXEC_POLICY_AMENDMENT: string;
|
|
72
74
|
/** The CLI frame a mapping could not place, kept so nothing is lost unseen. */
|
|
73
75
|
export declare const META_UNMAPPED_FRAME: string;
|
|
74
76
|
/**
|
|
75
|
-
* The
|
|
77
|
+
* The provider's OWN session id -- the identity `session/load` can resume with.
|
|
76
78
|
*
|
|
77
79
|
* This exists because its absence was a hole in the middle of resume. ACP's
|
|
78
|
-
* `sessionId` is minted by this server;
|
|
79
|
-
* a UUID
|
|
80
|
-
*
|
|
80
|
+
* `sessionId` is minted by this server; providers have their own identities
|
|
81
|
+
* (Claude's CLI accepts a UUID or title, while Codex uses its App Server thread
|
|
82
|
+
* id). The two were kept correctly separate inside the driver and then
|
|
83
|
+
* **never handed to the client**, so a client that
|
|
81
84
|
* stored the id `session/new` returned and passed it back to `session/load`
|
|
82
85
|
* was passing a string the CLI cannot resume.
|
|
83
86
|
*
|
package/dist/meta.js
CHANGED
|
@@ -81,15 +81,18 @@ export const META_THINKING_SIGNATURE = metaKey('thinking_signature');
|
|
|
81
81
|
export const META_THINKING_TOKENS_ESTIMATE = metaKey('thinking_tokens_estimate');
|
|
82
82
|
/** Structured rate-limit detail, alongside the human-readable notice. */
|
|
83
83
|
export const META_RATE_LIMIT = metaKey('rate_limit');
|
|
84
|
+
/** A command-line approval's persistent execpolicy amendment, tied to its ACP option. */
|
|
85
|
+
export const META_EXEC_POLICY_AMENDMENT = metaKey('execpolicy_amendment');
|
|
84
86
|
/** The CLI frame a mapping could not place, kept so nothing is lost unseen. */
|
|
85
87
|
export const META_UNMAPPED_FRAME = metaKey('unmapped_frame');
|
|
86
88
|
/**
|
|
87
|
-
* The
|
|
89
|
+
* The provider's OWN session id -- the identity `session/load` can resume with.
|
|
88
90
|
*
|
|
89
91
|
* This exists because its absence was a hole in the middle of resume. ACP's
|
|
90
|
-
* `sessionId` is minted by this server;
|
|
91
|
-
* a UUID
|
|
92
|
-
*
|
|
92
|
+
* `sessionId` is minted by this server; providers have their own identities
|
|
93
|
+
* (Claude's CLI accepts a UUID or title, while Codex uses its App Server thread
|
|
94
|
+
* id). The two were kept correctly separate inside the driver and then
|
|
95
|
+
* **never handed to the client**, so a client that
|
|
93
96
|
* stored the id `session/new` returned and passed it back to `session/load`
|
|
94
97
|
* was passing a string the CLI cannot resume.
|
|
95
98
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@particle-academy/prism-acp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Speak the Agent Client Protocol to a coding-agent CLI the user has already authenticated. No API key, no third-party adapter.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|