paseo-plugin-zcode-provider 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/NOTICE.md +29 -0
- package/README.md +112 -2
- package/client/account.tsx +827 -0
- package/client/diagnostics.tsx +379 -0
- package/client/runtime.tsx +296 -0
- package/client/settings.tsx +84 -0
- package/client/value.tsx +20 -0
- package/icon.svg +1 -0
- package/index.client.tsx +22 -0
- package/index.server.ts +39 -0
- package/package.json +77 -4
- package/paseo-plugin.json +6 -0
- package/server/account.ts +781 -0
- package/server/attachments.ts +150 -0
- package/server/build-info.ts +2 -0
- package/server/conversation.ts +319 -0
- package/server/diagnostics.ts +252 -0
- package/server/discovery/discover.ts +225 -0
- package/server/discovery/manifest.ts +36 -0
- package/server/discovery/types.ts +30 -0
- package/server/errors.ts +36 -0
- package/server/host/bridge.ts +490 -0
- package/server/host/schemas.ts +119 -0
- package/server/logger.ts +19 -0
- package/server/mapping.ts +270 -0
- package/server/models.ts +68 -0
- package/server/persistence.ts +146 -0
- package/server/presentation.ts +470 -0
- package/server/provider-status.ts +81 -0
- package/server/provider.ts +838 -0
- package/server/runtime/managed.ts +501 -0
- package/server/runtime/pins.ts +72 -0
- package/server/runtime-setup.ts +77 -0
- package/server/session-types.ts +49 -0
- package/server/session.ts +866 -0
- package/server/status.ts +89 -0
- package/server/timeline.ts +18 -0
- package/server/usage.ts +362 -0
- package/server/vendor/zcode/LICENSE +202 -0
- package/server/vendor/zcode/NOTICE.md +70 -0
- package/server/vendor/zcode/THIRD-PARTY-NOTICES.md +37 -0
- package/server/vendor/zcode/packages/model-option-map/src/compiler.ts +92 -0
- package/server/vendor/zcode/packages/model-option-map/src/evaluator.ts +214 -0
- package/server/vendor/zcode/packages/model-option-map/src/index.ts +5 -0
- package/server/vendor/zcode/packages/model-option-map/src/merge-patch.ts +97 -0
- package/server/vendor/zcode/packages/model-option-map/src/option-maps.ts +42 -0
- package/server/vendor/zcode/packages/model-option-map/src/parser.ts +240 -0
- package/server/vendor/zcode/packages/model-option-map/src/tokenizer.ts +141 -0
- package/server/vendor/zcode/packages/model-option-map/src/types.ts +36 -0
- package/server/vendor/zcode/packages/rpc/src/buffer.ts +88 -0
- package/server/vendor/zcode/packages/rpc/src/channelClient.ts +275 -0
- package/server/vendor/zcode/packages/rpc/src/channelServer.ts +283 -0
- package/server/vendor/zcode/packages/rpc/src/channels.shared.ts +66 -0
- package/server/vendor/zcode/packages/rpc/src/channels.ts +4 -0
- package/server/vendor/zcode/packages/rpc/src/delayedChannel.ts +17 -0
- package/server/vendor/zcode/packages/rpc/src/foundation.ts +260 -0
- package/server/vendor/zcode/packages/rpc/src/protocol.ts +397 -0
- package/server/vendor/zcode/packages/rpc/src/proxy-channel.ts +213 -0
- package/server/vendor/zcode/packages/rpc/src/serialization.ts +291 -0
- package/server/vendor/zcode/packages/shared/src/account-provider-state.ts +13 -0
- package/server/vendor/zcode/packages/shared/src/background-bash-output.ts +24 -0
- package/server/vendor/zcode/packages/shared/src/background-task-controls.ts +404 -0
- package/server/vendor/zcode/packages/shared/src/bash-output-display.ts +11 -0
- package/server/vendor/zcode/packages/shared/src/bots.ts +558 -0
- package/server/vendor/zcode/packages/shared/src/browser-use/backend.ts +80 -0
- package/server/vendor/zcode/packages/shared/src/browser-use/command-metadata.ts +170 -0
- package/server/vendor/zcode/packages/shared/src/browser-use/commands.ts +588 -0
- package/server/vendor/zcode/packages/shared/src/browser-use/result.ts +130 -0
- package/server/vendor/zcode/packages/shared/src/browser-use/snapshot.ts +77 -0
- package/server/vendor/zcode/packages/shared/src/command-types.ts +96 -0
- package/server/vendor/zcode/packages/shared/src/config-schema.ts +8 -0
- package/server/vendor/zcode/packages/shared/src/cuaAccessibilitySettings.ts +41 -0
- package/server/vendor/zcode/packages/shared/src/database-startup.ts +178 -0
- package/server/vendor/zcode/packages/shared/src/env.ts +63 -0
- package/server/vendor/zcode/packages/shared/src/execution-output-preview.ts +14 -0
- package/server/vendor/zcode/packages/shared/src/localTtft.ts +192 -0
- package/server/vendor/zcode/packages/shared/src/model-config.ts +123 -0
- package/server/vendor/zcode/packages/shared/src/model-execution.ts +23 -0
- package/server/vendor/zcode/packages/shared/src/model-provider-family.ts +171 -0
- package/server/vendor/zcode/packages/shared/src/model-provider-types.ts +81 -0
- package/server/vendor/zcode/packages/shared/src/model-selection.ts +60 -0
- package/server/vendor/zcode/packages/shared/src/oauth.ts +203 -0
- package/server/vendor/zcode/packages/shared/src/official-mcp-auth.ts +272 -0
- package/server/vendor/zcode/packages/shared/src/official-mcp-tool-error.ts +68 -0
- package/server/vendor/zcode/packages/shared/src/process-diagnostic.ts +42 -0
- package/server/vendor/zcode/packages/shared/src/protocol.ts +369 -0
- package/server/vendor/zcode/packages/shared/src/provider-family-connection-selection.ts +32 -0
- package/server/vendor/zcode/packages/shared/src/remoteAssetInstallMode.ts +11 -0
- package/server/vendor/zcode/packages/shared/src/remoteResourcePackages.ts +91 -0
- package/server/vendor/zcode/packages/shared/src/runtimeEnv.ts +315 -0
- package/server/vendor/zcode/packages/shared/src/settings-source.ts +10 -0
- package/server/vendor/zcode/packages/shared/src/usage-quota.ts +74 -0
- package/server/vendor/zcode/packages/shared/src/usage-stats.ts +462 -0
- package/server/vendor/zcode/packages/shared/src/validationAppSettings.ts +562 -0
- package/server/vendor/zcode/packages/shared/src/workspacePurpose.ts +2 -0
- package/server/vendor/zcode/packages/shared/src/wslUserValidation.ts +33 -0
- package/server/vendor/zcode/packages/shared/src/zcode-agent-policy.ts +25 -0
- package/server/vendor/zcode/packages/shared/src/zcode-media-policy.ts +10 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol/index.ts +3720 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-legacy-types.ts +529 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/apply.ts +218 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/attachment-ref.ts +14 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/command.ts +482 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/core.ts +100 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/create-workflow-display.ts +156 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/cuaPermission.ts +41 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/delta.ts +147 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/input-intent.ts +69 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/rows.ts +432 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/session-config.ts +43 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/sessions-index-workflow-activity.ts +195 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/sessions-index.ts +85 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/shared-context-import.ts +38 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/shared-context-ref.ts +10 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/snapshot.ts +509 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/submission.ts +5 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/toolDisplay.ts +264 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/transport.ts +1152 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-assembler.ts +574 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-binary.ts +65 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-codec.ts +240 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-fault.ts +39 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire.ts +159 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-artifacts.ts +291 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-observation-display.ts +281 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-row-meta.ts +163 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-run-settings-command.ts +62 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-runs-delta.ts +517 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-runs.ts +512 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workspace-config.ts +81 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workspace-hook-review.ts +210 -0
- package/server/vendor/zcode/packages/shared/src/zcode-task-mode-schema.ts +6 -0
- package/server/vendor/zcode/packages/shared/src/zcode-task-types-core.ts +1187 -0
- package/server/vendor/zcode/packages/shared/src/zcodeEndpoint.ts +296 -0
- package/server/vendor/zcode/provenance.json +405 -0
- package/shared/account.ts +201 -0
- package/shared/diagnostics.ts +52 -0
- package/shared/runtime-setup.ts +73 -0
- package/vendor/acp-registry/LICENSE +176 -0
- package/vendor/paseo/LICENSE +211 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { RestrictedCelError, type ModelOptionName } from "./types.js";
|
|
2
|
+
import type { RestrictedCelToken } from "./tokenizer.js";
|
|
3
|
+
|
|
4
|
+
export type RestrictedCelExpression =
|
|
5
|
+
| {
|
|
6
|
+
readonly type: "literal";
|
|
7
|
+
readonly value: string | number | boolean | null;
|
|
8
|
+
readonly offset: number;
|
|
9
|
+
}
|
|
10
|
+
| { readonly type: "input"; readonly offset: number }
|
|
11
|
+
| {
|
|
12
|
+
readonly type: "array";
|
|
13
|
+
readonly elements: readonly RestrictedCelExpression[];
|
|
14
|
+
readonly offset: number;
|
|
15
|
+
}
|
|
16
|
+
| {
|
|
17
|
+
readonly type: "object";
|
|
18
|
+
readonly entries: readonly {
|
|
19
|
+
readonly key: string;
|
|
20
|
+
readonly value: RestrictedCelExpression;
|
|
21
|
+
readonly offset: number;
|
|
22
|
+
}[];
|
|
23
|
+
readonly offset: number;
|
|
24
|
+
}
|
|
25
|
+
| {
|
|
26
|
+
readonly type: "unary";
|
|
27
|
+
readonly operator: "!" | "-" | "+";
|
|
28
|
+
readonly operand: RestrictedCelExpression;
|
|
29
|
+
readonly offset: number;
|
|
30
|
+
}
|
|
31
|
+
| {
|
|
32
|
+
readonly type: "binary";
|
|
33
|
+
readonly operator: string;
|
|
34
|
+
readonly left: RestrictedCelExpression;
|
|
35
|
+
readonly right: RestrictedCelExpression;
|
|
36
|
+
readonly offset: number;
|
|
37
|
+
}
|
|
38
|
+
| {
|
|
39
|
+
readonly type: "conditional";
|
|
40
|
+
readonly condition: RestrictedCelExpression;
|
|
41
|
+
readonly whenTrue: RestrictedCelExpression;
|
|
42
|
+
readonly whenFalse: RestrictedCelExpression;
|
|
43
|
+
readonly offset: number;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export function parseRestrictedCel(
|
|
47
|
+
tokens: readonly RestrictedCelToken[],
|
|
48
|
+
variableName: ModelOptionName,
|
|
49
|
+
): RestrictedCelExpression {
|
|
50
|
+
return new Parser(tokens, variableName).parse();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
class Parser {
|
|
54
|
+
#index = 0;
|
|
55
|
+
|
|
56
|
+
constructor(
|
|
57
|
+
private readonly tokens: readonly RestrictedCelToken[],
|
|
58
|
+
private readonly variableName: ModelOptionName,
|
|
59
|
+
) {}
|
|
60
|
+
|
|
61
|
+
parse(): RestrictedCelExpression {
|
|
62
|
+
const expression = this.parseConditional();
|
|
63
|
+
const trailing = this.current();
|
|
64
|
+
if (trailing.kind !== "eof") {
|
|
65
|
+
if (trailing.value === ".") {
|
|
66
|
+
throw new RestrictedCelError("member access is not supported", trailing.offset);
|
|
67
|
+
}
|
|
68
|
+
if (trailing.value === "(") {
|
|
69
|
+
throw new RestrictedCelError("function calls are not supported", trailing.offset);
|
|
70
|
+
}
|
|
71
|
+
throw new RestrictedCelError(
|
|
72
|
+
`unexpected token ${JSON.stringify(trailing.value)}`,
|
|
73
|
+
trailing.offset,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
return expression;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private parseConditional(): RestrictedCelExpression {
|
|
80
|
+
const condition = this.parseLogicalOr();
|
|
81
|
+
if (!this.consume("?")) return condition;
|
|
82
|
+
const whenTrue = this.parseConditional();
|
|
83
|
+
this.expect(":");
|
|
84
|
+
const whenFalse = this.parseConditional();
|
|
85
|
+
return { type: "conditional", condition, whenTrue, whenFalse, offset: condition.offset };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private parseLogicalOr(): RestrictedCelExpression {
|
|
89
|
+
return this.parseBinary(() => this.parseLogicalAnd(), new Set(["||"]));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private parseLogicalAnd(): RestrictedCelExpression {
|
|
93
|
+
return this.parseBinary(() => this.parseEquality(), new Set(["&&"]));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private parseEquality(): RestrictedCelExpression {
|
|
97
|
+
return this.parseBinary(() => this.parseRelational(), new Set(["==", "!="]));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private parseRelational(): RestrictedCelExpression {
|
|
101
|
+
return this.parseBinary(() => this.parseAdditive(), new Set(["<", "<=", ">", ">="]));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private parseAdditive(): RestrictedCelExpression {
|
|
105
|
+
return this.parseBinary(() => this.parseMultiplicative(), new Set(["+", "-"]));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private parseMultiplicative(): RestrictedCelExpression {
|
|
109
|
+
return this.parseBinary(() => this.parseUnary(), new Set(["*", "/", "%"]));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private parseBinary(
|
|
113
|
+
parseOperand: () => RestrictedCelExpression,
|
|
114
|
+
operators: ReadonlySet<string>,
|
|
115
|
+
): RestrictedCelExpression {
|
|
116
|
+
let expression = parseOperand();
|
|
117
|
+
while (this.current().kind === "operator" && operators.has(this.current().value)) {
|
|
118
|
+
const operator = this.advance();
|
|
119
|
+
expression = {
|
|
120
|
+
type: "binary",
|
|
121
|
+
operator: operator.value,
|
|
122
|
+
left: expression,
|
|
123
|
+
right: parseOperand(),
|
|
124
|
+
offset: operator.offset,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return expression;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private parseUnary(): RestrictedCelExpression {
|
|
131
|
+
const token = this.current();
|
|
132
|
+
if (
|
|
133
|
+
token.kind === "operator" &&
|
|
134
|
+
(token.value === "!" || token.value === "-" || token.value === "+")
|
|
135
|
+
) {
|
|
136
|
+
this.advance();
|
|
137
|
+
return {
|
|
138
|
+
type: "unary",
|
|
139
|
+
operator: token.value,
|
|
140
|
+
operand: this.parseUnary(),
|
|
141
|
+
offset: token.offset,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
return this.parsePrimary();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private parsePrimary(): RestrictedCelExpression {
|
|
148
|
+
const token = this.advance();
|
|
149
|
+
if (token.kind === "number") {
|
|
150
|
+
const value = Number(token.value);
|
|
151
|
+
if (!Number.isFinite(value) || (Number.isInteger(value) && !Number.isSafeInteger(value))) {
|
|
152
|
+
throw new RestrictedCelError("number literal is not JSON-safe", token.offset);
|
|
153
|
+
}
|
|
154
|
+
return { type: "literal", value, offset: token.offset };
|
|
155
|
+
}
|
|
156
|
+
if (token.kind === "string")
|
|
157
|
+
return { type: "literal", value: token.value, offset: token.offset };
|
|
158
|
+
if (token.kind === "identifier") {
|
|
159
|
+
if (this.current().value === "(") {
|
|
160
|
+
throw new RestrictedCelError("function calls are not supported", this.current().offset);
|
|
161
|
+
}
|
|
162
|
+
if (token.value === this.variableName) return { type: "input", offset: token.offset };
|
|
163
|
+
if (token.value === "true" || token.value === "false") {
|
|
164
|
+
return { type: "literal", value: token.value === "true", offset: token.offset };
|
|
165
|
+
}
|
|
166
|
+
if (token.value === "null") return { type: "literal", value: null, offset: token.offset };
|
|
167
|
+
throw new RestrictedCelError(
|
|
168
|
+
`unknown identifier ${JSON.stringify(token.value)}`,
|
|
169
|
+
token.offset,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
if (token.value === "(") {
|
|
173
|
+
const expression = this.parseConditional();
|
|
174
|
+
this.expect(")");
|
|
175
|
+
return expression;
|
|
176
|
+
}
|
|
177
|
+
if (token.value === "[") return this.parseArray(token.offset);
|
|
178
|
+
if (token.value === "{") return this.parseObject(token.offset);
|
|
179
|
+
throw new RestrictedCelError(`unexpected token ${JSON.stringify(token.value)}`, token.offset);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private parseArray(offset: number): RestrictedCelExpression {
|
|
183
|
+
const elements: RestrictedCelExpression[] = [];
|
|
184
|
+
if (!this.consume("]")) {
|
|
185
|
+
do elements.push(this.parseConditional());
|
|
186
|
+
while (this.consume(","));
|
|
187
|
+
this.expect("]");
|
|
188
|
+
}
|
|
189
|
+
return { type: "array", elements: Object.freeze(elements), offset };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private parseObject(offset: number): RestrictedCelExpression {
|
|
193
|
+
const entries: { key: string; value: RestrictedCelExpression; offset: number }[] = [];
|
|
194
|
+
const keys = new Set<string>();
|
|
195
|
+
if (!this.consume("}")) {
|
|
196
|
+
do {
|
|
197
|
+
const key = this.advance();
|
|
198
|
+
if (key.kind !== "string") {
|
|
199
|
+
throw new RestrictedCelError("object keys must be string literals", key.offset);
|
|
200
|
+
}
|
|
201
|
+
if (keys.has(key.value)) {
|
|
202
|
+
throw new RestrictedCelError(
|
|
203
|
+
`duplicate object key ${JSON.stringify(key.value)}`,
|
|
204
|
+
key.offset,
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
keys.add(key.value);
|
|
208
|
+
this.expect(":");
|
|
209
|
+
entries.push({ key: key.value, value: this.parseConditional(), offset: key.offset });
|
|
210
|
+
} while (this.consume(","));
|
|
211
|
+
this.expect("}");
|
|
212
|
+
}
|
|
213
|
+
return { type: "object", entries: Object.freeze(entries), offset };
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private consume(value: string): boolean {
|
|
217
|
+
if (this.current().value !== value) return false;
|
|
218
|
+
this.#index += 1;
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private expect(value: string): RestrictedCelToken {
|
|
223
|
+
const token = this.current();
|
|
224
|
+
if (token.value !== value) {
|
|
225
|
+
throw new RestrictedCelError(`expected ${JSON.stringify(value)}`, token.offset);
|
|
226
|
+
}
|
|
227
|
+
this.#index += 1;
|
|
228
|
+
return token;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
private advance(): RestrictedCelToken {
|
|
232
|
+
const token = this.current();
|
|
233
|
+
if (token.kind !== "eof") this.#index += 1;
|
|
234
|
+
return token;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private current(): RestrictedCelToken {
|
|
238
|
+
return this.tokens[this.#index] ?? this.tokens[this.tokens.length - 1]!;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { RestrictedCelError } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export type RestrictedCelTokenKind =
|
|
4
|
+
| "identifier"
|
|
5
|
+
| "string"
|
|
6
|
+
| "number"
|
|
7
|
+
| "operator"
|
|
8
|
+
| "punctuation"
|
|
9
|
+
| "eof";
|
|
10
|
+
|
|
11
|
+
export interface RestrictedCelToken {
|
|
12
|
+
readonly kind: RestrictedCelTokenKind;
|
|
13
|
+
readonly value: string;
|
|
14
|
+
readonly offset: number;
|
|
15
|
+
readonly end: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const DOUBLE_OPERATORS = new Set(["&&", "||", "==", "!=", "<=", ">="]);
|
|
19
|
+
const SINGLE_OPERATORS = new Set(["+", "-", "*", "/", "%", "!", "<", ">"]);
|
|
20
|
+
const PUNCTUATION = new Set(["{", "}", "[", "]", "(", ")", ",", ":", "?", "."]);
|
|
21
|
+
|
|
22
|
+
export function tokenizeRestrictedCel(source: string): readonly RestrictedCelToken[] {
|
|
23
|
+
const tokens: RestrictedCelToken[] = [];
|
|
24
|
+
let offset = 0;
|
|
25
|
+
while (offset < source.length) {
|
|
26
|
+
const character = source[offset]!;
|
|
27
|
+
if (/\s/u.test(character)) {
|
|
28
|
+
offset += 1;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (character === "'" || character === '"') {
|
|
33
|
+
const token = readString(source, offset, character);
|
|
34
|
+
tokens.push(token);
|
|
35
|
+
offset = token.end;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (/[0-9]/u.test(character)) {
|
|
40
|
+
const token = readNumber(source, offset);
|
|
41
|
+
tokens.push(token);
|
|
42
|
+
offset = token.end;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (/[A-Za-z_]/u.test(character)) {
|
|
47
|
+
const end = readWhile(source, offset + 1, /[A-Za-z0-9_]/u);
|
|
48
|
+
tokens.push({ kind: "identifier", value: source.slice(offset, end), offset, end });
|
|
49
|
+
offset = end;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const pair = source.slice(offset, offset + 2);
|
|
54
|
+
if (DOUBLE_OPERATORS.has(pair)) {
|
|
55
|
+
tokens.push({ kind: "operator", value: pair, offset, end: offset + 2 });
|
|
56
|
+
offset += 2;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (SINGLE_OPERATORS.has(character)) {
|
|
60
|
+
tokens.push({ kind: "operator", value: character, offset, end: offset + 1 });
|
|
61
|
+
offset += 1;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (PUNCTUATION.has(character)) {
|
|
65
|
+
tokens.push({ kind: "punctuation", value: character, offset, end: offset + 1 });
|
|
66
|
+
offset += 1;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
throw new RestrictedCelError(`unsupported token ${JSON.stringify(character)}`, offset);
|
|
70
|
+
}
|
|
71
|
+
tokens.push({ kind: "eof", value: "", offset: source.length, end: source.length });
|
|
72
|
+
return Object.freeze(tokens);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function readNumber(source: string, offset: number): RestrictedCelToken {
|
|
76
|
+
const match = /^(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/u.exec(source.slice(offset));
|
|
77
|
+
if (!match) throw new RestrictedCelError("invalid number literal", offset);
|
|
78
|
+
const value = match[0];
|
|
79
|
+
const end = offset + value.length;
|
|
80
|
+
return { kind: "number", value, offset, end };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function readString(source: string, offset: number, quote: "'" | '"'): RestrictedCelToken {
|
|
84
|
+
let cursor = offset + 1;
|
|
85
|
+
let value = "";
|
|
86
|
+
while (cursor < source.length) {
|
|
87
|
+
const character = source[cursor]!;
|
|
88
|
+
if (character === quote) {
|
|
89
|
+
return { kind: "string", value, offset, end: cursor + 1 };
|
|
90
|
+
}
|
|
91
|
+
if (character === "\n" || character === "\r") {
|
|
92
|
+
throw new RestrictedCelError("unterminated string literal", offset);
|
|
93
|
+
}
|
|
94
|
+
if (character !== "\\") {
|
|
95
|
+
value += character;
|
|
96
|
+
cursor += 1;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const escapeOffset = cursor;
|
|
101
|
+
cursor += 1;
|
|
102
|
+
const escaped = source[cursor];
|
|
103
|
+
if (escaped === undefined) {
|
|
104
|
+
throw new RestrictedCelError("unterminated string escape", escapeOffset);
|
|
105
|
+
}
|
|
106
|
+
const simpleEscape = SIMPLE_ESCAPES[escaped];
|
|
107
|
+
if (simpleEscape !== undefined) {
|
|
108
|
+
value += simpleEscape;
|
|
109
|
+
cursor += 1;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (escaped === "u") {
|
|
113
|
+
const digits = source.slice(cursor + 1, cursor + 5);
|
|
114
|
+
if (!/^[0-9A-Fa-f]{4}$/u.test(digits)) {
|
|
115
|
+
throw new RestrictedCelError("invalid unicode escape", escapeOffset);
|
|
116
|
+
}
|
|
117
|
+
value += String.fromCharCode(Number.parseInt(digits, 16));
|
|
118
|
+
cursor += 5;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
throw new RestrictedCelError(`unsupported string escape \\${escaped}`, escapeOffset);
|
|
122
|
+
}
|
|
123
|
+
throw new RestrictedCelError("unterminated string literal", offset);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const SIMPLE_ESCAPES: Readonly<Record<string, string>> = Object.freeze({
|
|
127
|
+
"'": "'",
|
|
128
|
+
'"': '"',
|
|
129
|
+
"\\": "\\",
|
|
130
|
+
b: "\b",
|
|
131
|
+
f: "\f",
|
|
132
|
+
n: "\n",
|
|
133
|
+
r: "\r",
|
|
134
|
+
t: "\t",
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
function readWhile(source: string, offset: number, pattern: RegExp): number {
|
|
138
|
+
let cursor = offset;
|
|
139
|
+
while (cursor < source.length && pattern.test(source[cursor]!)) cursor += 1;
|
|
140
|
+
return cursor;
|
|
141
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
2
|
+
export type JsonValue = JsonPrimitive | JsonObject | readonly JsonValue[];
|
|
3
|
+
|
|
4
|
+
export interface JsonObject {
|
|
5
|
+
readonly [key: string]: JsonValue;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type RestrictedCelValue = string | number;
|
|
9
|
+
export type ModelOptionName = "reasoningLevel" | "maxOutputTokens";
|
|
10
|
+
|
|
11
|
+
export interface RestrictedCelProgram {
|
|
12
|
+
readonly source: string;
|
|
13
|
+
evaluate(input: RestrictedCelValue): JsonValue;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface ModelOptionMapProgram {
|
|
17
|
+
readonly source: string;
|
|
18
|
+
evaluate(input: RestrictedCelValue): JsonObject;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class RestrictedCelError extends Error {
|
|
22
|
+
readonly offset: number;
|
|
23
|
+
|
|
24
|
+
constructor(message: string, offset: number) {
|
|
25
|
+
super(`${message} at offset ${offset}`);
|
|
26
|
+
this.name = "RestrictedCelError";
|
|
27
|
+
this.offset = offset;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class ModelOptionMapError extends Error {
|
|
32
|
+
constructor(message: string) {
|
|
33
|
+
super(message);
|
|
34
|
+
this.name = "ModelOptionMapError";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 0.5: 跨平台 Buffer 抽象
|
|
3
|
+
*
|
|
4
|
+
* VS Code 需要在 Node.js (Buffer) 和浏览器 (Uint8Array) 之间统一二进制操作。
|
|
5
|
+
* VSBuffer 是对 Uint8Array 的薄封装,提供统一的读写接口。
|
|
6
|
+
*
|
|
7
|
+
* 这是序列化层和传输层的基础。
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export class VSBuffer {
|
|
11
|
+
readonly buffer: Uint8Array;
|
|
12
|
+
readonly byteLength: number;
|
|
13
|
+
|
|
14
|
+
private constructor(buffer: Uint8Array) {
|
|
15
|
+
this.buffer = buffer;
|
|
16
|
+
this.byteLength = buffer.byteLength;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** 分配指定大小的空 buffer */
|
|
20
|
+
static alloc(byteLength: number): VSBuffer {
|
|
21
|
+
return new VSBuffer(new Uint8Array(byteLength));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** 包装已有的 Uint8Array */
|
|
25
|
+
static wrap(buffer: Uint8Array): VSBuffer {
|
|
26
|
+
return new VSBuffer(buffer);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** 从字符串创建 buffer (UTF-8) */
|
|
30
|
+
static fromString(str: string): VSBuffer {
|
|
31
|
+
const encoder = new TextEncoder();
|
|
32
|
+
return new VSBuffer(encoder.encode(str));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** 拼接多个 buffer */
|
|
36
|
+
static concat(buffers: VSBuffer[], totalLength?: number): VSBuffer {
|
|
37
|
+
const len = totalLength ?? buffers.reduce((sum, b) => sum + b.byteLength, 0);
|
|
38
|
+
const result = VSBuffer.alloc(len);
|
|
39
|
+
let offset = 0;
|
|
40
|
+
for (const buf of buffers) {
|
|
41
|
+
result.set(buf, offset);
|
|
42
|
+
offset += buf.byteLength;
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** 转为 UTF-8 字符串 */
|
|
48
|
+
toString(): string {
|
|
49
|
+
const decoder = new TextDecoder();
|
|
50
|
+
return decoder.decode(this.buffer);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** 切片 */
|
|
54
|
+
slice(start: number, end?: number): VSBuffer {
|
|
55
|
+
return new VSBuffer(this.buffer.slice(start, end));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** 拷贝数据到 this buffer 的指定位置 */
|
|
59
|
+
set(source: VSBuffer | Uint8Array, offset = 0): void {
|
|
60
|
+
const raw = source instanceof VSBuffer ? source.buffer : source;
|
|
61
|
+
this.buffer.set(raw, offset);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
readUInt8(offset: number): number {
|
|
65
|
+
return this.buffer[offset];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
writeUInt8(value: number, offset: number): void {
|
|
69
|
+
this.buffer[offset] = value;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
readUInt32BE(offset: number): number {
|
|
73
|
+
return (
|
|
74
|
+
((this.buffer[offset] << 24) |
|
|
75
|
+
(this.buffer[offset + 1] << 16) |
|
|
76
|
+
(this.buffer[offset + 2] << 8) |
|
|
77
|
+
this.buffer[offset + 3]) >>>
|
|
78
|
+
0
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
writeUInt32BE(value: number, offset: number): void {
|
|
83
|
+
this.buffer[offset] = (value >>> 24) & 0xff;
|
|
84
|
+
this.buffer[offset + 1] = (value >>> 16) & 0xff;
|
|
85
|
+
this.buffer[offset + 2] = (value >>> 8) & 0xff;
|
|
86
|
+
this.buffer[offset + 3] = value & 0xff;
|
|
87
|
+
}
|
|
88
|
+
}
|